ทำไมสิ่งนี้ไม่ทำงาน “ ls * .txt | xargs cat> all.txt” (ไฟล์ทั้งหมดลงในเอกสาร txt เดี่ยว)


20

ทำไมสิ่งนี้ไม่ทำงาน

ls *.txt | xargs cat > all.txt

(ฉันต้องการที่จะเข้าร่วมเนื้อหาของไฟล์ข้อความทั้งหมดลงในไฟล์ 'all.txt' ไฟล์เดียว) ค้นหาด้วย -exec ควรใช้งานได้ แต่ฉันอยากจะเข้าใจไวยากรณ์ xargs จริงๆ

ขอบคุณ


1
แม้ว่าจะไม่ได้ใช้lsสำหรับการนี้ หากคุณไม่สามารถใช้งานได้จริง ๆcat *.txt >all.txtให้ลองprintf '%s\0' *.txt | xargs -r0 cat >allแล้วmv all all.txtหลีกเลี่ยงการอ้างอิงไฟล์เอง
tripleee

คำตอบ:


27

ls *.txt | xargs cat >> all.txt

อาจทำงานได้ดีขึ้นเล็กน้อยเนื่องจากมันจะผนวกกับ all.txt แทนที่จะสร้างขึ้นอีกครั้งหลังจากแต่ละไฟล์

โดยวิธีการcat *.txt >all.txtก็จะทำงาน :-)


6
cat * .txt> all.txt นั้นดีกว่าโดยธรรมชาติ ขอบคุณ
ajo

1
อย่างไรก็ตาม ... xargs cat >> all.txt หรือ> all.txt ส่งคืนข้อผิดพลาดเสมอกับ xargs: อัญประกาศเดี่ยวที่ไม่ตรงกัน ... เป็นเพราะ xargs ใช้ทุกอย่างหลังจากที่มันเป็นคำสั่งหรือไม่
ajo

1
คุณมีชื่อไฟล์ด้วยช่องว่างหรือไม่? หากเป็นเช่นนั้นให้ใช้บางอย่างเช่น "find / your / path -iname '* .txt' -print0 | xargs -0 cat >> all.txt" แทน
Janne Pikkarainen

1
ไม่ฉันแทนที่ช่องว่างชื่อไฟล์ที่มี แต่คิดว่าชื่อไฟล์บางชื่อมีแนวโน้มที่จะรวมคำพูดเดียวใน listing_O'Connor .txt นี่อาจเป็นปัญหา!
ajo

ใช่นั่นเป็นปัญหาแล้ว :) วิธีที่ง่ายและปลอดภัยที่สุดคือการใช้ find ด้วย -print0 รวมกับ xargs -0 - จากนั้น chain ทั้งหมดจะใช้อักขระ NULL เป็นตัวคั่นและช่องว่างและอักขระพิเศษจะได้รับการดูแลโดยอัตโนมัติ
Janne Pikkarainen

3

หากชื่อไฟล์บางส่วนของคุณมี ', "หรือช่องว่าง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


1

all.txt เป็นไฟล์ในไดเรกทอรีเดียวกันดังนั้น cat จะสับสนเมื่อต้องการเขียนจากไฟล์เดียวกันไปยังไฟล์เดียวกัน

ในทางกลับกัน:

ls *.txt | xargs cat > tmp/all.txt

สิ่งนี้จะอ่านจาก textfiles ในไดเรกทอรีปัจจุบันของคุณไปยัง all.txt ในไดเรกทอรีย่อย (ไม่รวมอยู่ใน*.txt)


ยังคงเป็นข้อผิดพลาดต่อไปนี้: xargs: อัญประกาศเดี่ยวที่ไม่ตรงกัน โดยเครื่องหมายอัญประกาศเริ่มต้นเป็นพิเศษสำหรับ xargs เว้นแต่ว่าคุณจะใช้ตัวเลือก -0
ajo

1
คุณมีไฟล์. txt ที่มี singlequote ในชื่อหรือไม่?
Jeremy Smyth

0

คุณอาจเจอข้อจำกัดความยาวบรรทัดคำสั่ง ส่วนหนึ่งของเหตุผลในการใช้งาน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 บอกให้มันคาดหวังอินพุตในรูปแบบเดียวกัน สิ่งนี้จะใช้ได้แม้ว่าคุณจะมีชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.