xargs - แทนที่ / -I สำหรับอาร์กิวเมนต์เดียว


10

ฉันพยายามใช้ xargs เพื่อรันคำสั่งสำหรับแต่ละอาร์กิวเมนต์ที่ให้ แต่น่าเสียดายที่แฟล็ก --replace / -I ดูเหมือนจะไม่ทำงานอย่างถูกต้องเมื่อเชื่อมต่อกับ -n ดูเหมือนว่า {} จะขยายไปสู่รายการอาร์กิวเมนต์ทั้งหมดที่อ่านจาก stdin โดยไม่คำนึงถึงตัวเลือก -n

น่าเสียดายที่ตัวอย่างทั้งหมดบนเว็บดูเหมือนจะเป็นคำสั่ง (mv, cp, rm) ซึ่งจะใช้อาร์กิวเมนต์หลายตัวที่ {} ถูกขยาย

ตัวอย่างเช่นเมื่อทำงาน:

echo a b c d | xargs -n 1 -I {} echo derp {}

ผลลัพธ์คือ:

derp a b c d

แต่ฉันคาดว่า:

derp a
derp b
derp c
derp d

อย่างไรก็ตามการรันโดยไม่มี -I {} จะทำให้ได้ผลลัพธ์ที่ต้องการ:

echo a b c d | xargs -n 1 echo derp
derp a
derp b
derp c
derp d

มีวิธีใดบ้างที่จะบรรลุเป้าหมายนี้ด้วย xargs? ความตั้งใจสูงสุดของฉันคือการใช้มันเพื่อเรียกใช้หลายรอบ (parralel) ssh เช่น

echo server{1..90} | xargs -n 1 -P 0 -I {} ssh {} 'echo $SOME_HOST_INFO'

ฉันกำลังใช้งานxargs (GNU findutils) 4.4.2RHEL 6.3


2
ที่น่าสนใจก็ทำงานตามที่คุณตั้งใจกับ BSD xargsแต่ไม่ xargsGNU
slhck

1
man xargsเปิด-I: Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.ดังนั้นจึงทำงานตามที่ออกแบบไว้
Daniel Beck

@ Andréเนื่องจากความตั้งใจของคุณคือการเรียกใช้ taks ในแบบคู่ขนานคุณได้ดู GNU ขนานกันหรือไม่ มันทำงานได้ดี ข้อจำกัดความรับผิดชอบ: ฉันจัดเก็บสำหรับ Debian
rbrito

GNU parallel ดูเหมือนจะเป็นการแทนที่ที่ดี แต่น่าเสียดายที่ฉันไม่สามารถติดตั้งบนโฮสต์นี้ได้
André Fernandes

@ AndréFernandesคุณช่วยอธิบายได้ไหมถ้าเหตุผลของคุณไม่ครอบคลุมโดยoletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

คำตอบ:


5

คุณสามารถสะท้อนกับบรรทัดใหม่เพื่อให้ได้ผลลัพธ์ที่คาดหวัง ในกรณีของคุณด้วยการขยายเซิร์ฟเวอร์ที่จะ:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4

แนวคิดขึ้นบรรทัดใหม่แก้ปัญหาได้ (ไม่ใช่ตัวอย่างที่แน่นอนของคุณ): เซิร์ฟเวอร์ echo {1..4} | tr '' '\ n' | xargs -I {} echo derp {} derp server1 derp server2 derp server3 derp server4
André Fernandes

ขออภัยทดสอบด้วยzsh... แก้ไขคำตอบของฉัน echoต้องการ-eตัวเลือก
ahilsend

2

คุณสามารถใช้ประโยชน์จากท่อพิเศษแบบนี้

echo a b c d | xargs -n1 | xargs -I{} echo derp {}
derp a
derp b
derp c
derp d

การใช้ xargs 'echos' ระดับกลางแต่ละตัวอักษร 'abcd' เป็นรายบุคคลเนื่องจากตัวเลือก '-n1' สิ่งนี้ทำให้ตัวอักษรแต่ละตัวบนเส้นของตัวเองเช่นนี้

echo a b c d | xargs -n1
a
b
c
d 

สิ่งสำคัญคือต้องเข้าใจเมื่อใช้ -I (การแทนที่สตริง) xargs หมายถึง -L ซึ่งดำเนินการคำสั่งยูทิลิตี (ในเคสของคุณ echo) หนึ่งครั้งต่อบรรทัด นอกจากนี้คุณไม่สามารถใช้ -n กับ -L เนื่องจากเป็นเอกสิทธิ์เฉพาะบุคคลร่วมกัน

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