ทำไมสิ่งนี้ไม่ทำงาน
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หลีกเลี่ยงการอ้างอิงไฟล์เอง