xargs -I replace-str ตัวเลือกที่แตกต่าง


16

จากความเข้าใจของฉันต่อไปนี้ควรมีความหมายเหมือนกันทุกประการ:

ls -1 | xargs file {}
ls -1 | xargs -I{} file {}

หากไม่ได้ระบุตัวเลือก -I ไว้ค่าเริ่มต้นคือ -I {}

ฉันต้องการแสดงรายการไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันและเรียกใช้fileคำสั่งในแต่ละไฟล์ บางแห่งมีช่องว่างในชื่อ อย่างไรก็ตามฉันสังเกตเห็นความแตกต่าง ดูด้านล่าง:

$ ls -1
Hello World
$ ls -1 | xargs file {}
{}:    ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory

ด้วย -I {} ที่ระบุไว้อย่างชัดเจนช่องว่างในชื่อไฟล์จะถือว่าเป็นไปตามที่คาดไว้


3
"ถ้าไม่ได้ระบุตัวเลือก -I ไว้ค่าเริ่มต้นคือ -I {}" - สิ่งนี้ไม่ถูกต้องอย่างน้อย GNU xargs
jjlin

ฉันเข้าใจความผิดพลาดของฉัน ฉันควรจะระบุอย่างใดอย่างหนึ่งหรือxargs file ไม่ควรจะเป็นxargs -I{} file {} xargs file {}ผมคิดว่าเมื่อระบุอย่างชัดเจน -I {} file "Hello World"ทุบตีจะรักษามันเป็น โดยไม่ต้อง -I {} file Hello Worldก็จะถือว่าเป็น
foresightyj

1
(1) การสนทนานี้มีส่วนเกี่ยวข้องกับเชลล์ (ทุบตี) เพียงเล็กน้อย (2) เป็นเรื่องดีที่คุณรู้ว่า-1ตัวเลือกเป็นไปlsตามค่าเริ่มต้นเมื่อเอาต์พุตของlsไฟล์หรือไพพ์ดังนั้นคุณไม่จำเป็นต้องใช้ที่นี่ (3) คุณกำลังสับสน-Iกับตัวเลือกที่คัดค้าน-i(ตัวพิมพ์เล็กI) -ifooเทียบเท่ากับ-Ifooแต่ธรรมดาเทียบเท่ากับ-i แต่การใช้งาน-I{} -I{}(4) ถ้าคุณต้องการทำสิ่งที่คุณพูดว่าต้องการทำจริงๆทำไมไม่เพียงแค่พูดfile *?
Scott

@Scott ความตั้งใจดั้งเดิมของฉันคือเขียน `ค้นหา -name "* .mov" | xargs -I {} file {} `เพื่อค้นหาไฟล์ mov ทั้งหมดซ้ำและทำงานfileกับมัน lsแต่ฉันมากับตัวอย่างที่ง่ายโดยใช้ คุณพูดถูก สำหรับสิ่งfile *ที่ดีที่สุด
foresightyj

1
พบ-execมี
Cristian Ciupitu

คำตอบ:


20

-Iต้องมีตัวยึดที่กำหนดไว้ -iตัวเลือกที่จะถือว่า{}เป็นตัวยึด นี่คือที่ที่ฉันพบข้อสันนิษฐานใด ๆ ของ {} man xargsอย่างน้อยใน Cygwin และ CentOS

xargs ที่เรียกใช้โดยไม่มีตัวเลือกอย่างใดอย่างหนึ่งไม่จำเป็นต้องมีตัวยึดตำแหน่งและจะเพิ่ม STDIN ต่อท้ายอาร์กิวเมนต์

เพียงเพิ่มechoตัวอย่างของคุณเพื่อดูว่า xargs กำลังทำอะไร:

$ ls -1
Hello World/

ตัวอย่างของคุณผิดใช้{}:

$ ls -1 | xargs echo file {}
file {} Hello World/

ดังนั้นfilecmd เห็น args {} Hello Worldและข้อผิดพลาด

หากคุณต้องการใช้อย่างชัดเจน{}ในการโทร xargs ของคุณ:

$ ls -1 | xargs -i echo file {}
file Hello World/

หรือไม่มีตัวยึดตำแหน่ง:

$ ls -1 | xargs echo file
file Hello World/

xargs ตามที่เรียกข้างต้นไม่จำเป็นต้องมี {} มันผนวก STDIN ต่อท้ายคำสั่งโดยไม่มีตัวยึด โดยปกติแล้วการใช้ {} หมายถึงคุณต้องการให้ STDIN อยู่ตรงกลางของ cmd เพื่อดำเนินการดังที่:

$ ls -1 | xargs -i mv {} /path/to/someplace/.

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