ทำไมสิ่งนี้ไม่ทำงาน
ls *.txt | xargs cat > all.txt
(ฉันต้องการที่จะเข้าร่วมเนื้อหาของไฟล์ข้อความทั้งหมดลงในไฟล์ 'all.txt' ไฟล์เดียว) ค้นหาด้วย -exec ควรใช้งานได้ แต่ฉันอยากจะเข้าใจไวยากรณ์ xargs จริงๆ
ขอบคุณ
ทำไมสิ่งนี้ไม่ทำงาน
ls *.txt | xargs cat > all.txt
(ฉันต้องการที่จะเข้าร่วมเนื้อหาของไฟล์ข้อความทั้งหมดลงในไฟล์ 'all.txt' ไฟล์เดียว) ค้นหาด้วย -exec ควรใช้งานได้ แต่ฉันอยากจะเข้าใจไวยากรณ์ xargs จริงๆ
ขอบคุณ
คำตอบ:
ls *.txt | xargs cat >> all.txt
อาจทำงานได้ดีขึ้นเล็กน้อยเนื่องจากมันจะผนวกกับ all.txt แทนที่จะสร้างขึ้นอีกครั้งหลังจากแต่ละไฟล์
โดยวิธีการcat *.txt >all.txt
ก็จะทำงาน :-)
หากชื่อไฟล์บางส่วนของคุณมี ', "หรือช่องว่างxargs
จะล้มเหลวเนื่องจากปัญหาตัวคั่น
โดยทั่วไปไม่เคยวิ่งxargs
โดยไม่มี -0 เพราะมันจะกลับมากัดคุณได้ซักวัน
พิจารณาใช้ GNU Parallel แทน:
ls *.txt | parallel cat > tmp/all.txt
หรือถ้าคุณต้องการ:
ls *.txt | parallel cat >> tmp/all.txt
เรียนรู้เพิ่มเติมเกี่ยวกับ GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ
all.txt
เป็นไฟล์ในไดเรกทอรีเดียวกันดังนั้น cat จะสับสนเมื่อต้องการเขียนจากไฟล์เดียวกันไปยังไฟล์เดียวกัน
ในทางกลับกัน:
ls *.txt | xargs cat > tmp/all.txt
สิ่งนี้จะอ่านจาก textfiles ในไดเรกทอรีปัจจุบันของคุณไปยัง all.txt ในไดเรกทอรีย่อย (ไม่รวมอยู่ใน*.txt
)
คุณอาจเจอข้อจำกัดความยาวบรรทัดคำสั่ง ส่วนหนึ่งของเหตุผลในการใช้งานxargs
คือมันแยกอินพุตเป็นส่วนขนาดบรรทัดคำสั่งที่ปลอดภัย ลองจินตนาการถึงสถานการณ์ที่คุณมีไฟล์. txt หลายแสนไฟล์ในไดเรกทอรี ls *.txt
จะล้มเหลว คุณจะต้องทำ
ls | grep .txt$ |xargs cat > /some/other/path/all.txt
.txt$
ในกรณีนี้คือนิพจน์ทั่วไปที่ตรงกับทุกอย่างที่ลงท้ายด้วย. txt (ดังนั้นจึงไม่เหมือน*.txt
กันเพราะถ้าคุณมีไฟล์ชื่อatxt
แล้ว*.txt
จะไม่ตรงกับมัน แต่นิพจน์ทั่วไปจะเป็นเช่นนั้น)
การใช้เส้นทางอื่นเป็นเพราะอย่างที่คำตอบอื่น ๆ ชี้ให้เห็น all.txt นั้นถูกจับคู่โดยรูปแบบ*.txt
ดังนั้นจะมีข้อขัดแย้งระหว่างอินพุตและเอาต์พุต
โปรดทราบว่าหากคุณมีไฟล์ใด ๆ ที่'
อยู่ในชื่อ (และนี่อาจเป็นสาเหตุของunmatched single quote
ข้อผิดพลาด) คุณจะต้องทำ
ls | grep --null .txt$ | xargs -0 cat > /some/other/path/all.txt
ตัวเลือก --null บอกให้ grep ใช้เอาต์พุตที่คั่นด้วย\0
อักขระ (aka null) แทนการขึ้นบรรทัดใหม่และ-0
ตัวเลือก `xargs บอกให้มันคาดหวังอินพุตในรูปแบบเดียวกัน สิ่งนี้จะใช้ได้แม้ว่าคุณจะมีชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่
ls
สำหรับการนี้ หากคุณไม่สามารถใช้งานได้จริง ๆcat *.txt >all.txt
ให้ลองprintf '%s\0' *.txt | xargs -r0 cat >all
แล้วmv all all.txt
หลีกเลี่ยงการอ้างอิงไฟล์เอง