การส่งอาร์กิวเมนต์ไปยังหลายคำสั่งในบรรทัดเดียว


10

ฉันต้องการที่จะเรียกใช้หลายคำสั่งในไฟล์เดียวกันในบรรทัดเดียว วิธีที่ฉันทำในขณะนี้คือ:

commandA file && commandB file && perl -ne '...' file

สัญชาตญาณของฉันบอกฉันว่าควรมีวิธีที่จะให้อาร์กิวเมนต์ชื่อไฟล์เพียงครั้งเดียวและท่อไปยังคำสั่งทั้งสองพร้อมกันผ่านxargsหรือสิ่งที่คล้ายกัน:

find file | xargs commandA && xargs commandB && xargs perl -ne '...'

เมื่อฉันลองสิ่งนี้คำสั่งแรกเท่านั้นที่จะทำงาน ฉันจะบรรลุสิ่งที่ฉันต้องการจะทำอย่างไร

คำตอบ:


12

คุณสามารถกำหนดตัวแปรท้องถิ่นสำหรับสิ่งนี้:

f=file; commandA $f && commandB $f && ...

คุณสามารถดำเนินการทั้งหมดโดยไม่มีเงื่อนไข (แทนที่&&ด้วย;) หรือขนาน (แทนที่&&ด้วย&)

หรือคุณสามารถใช้การขยายประวัติเชลล์เพื่ออ้างอิงอาร์กิวเมนต์ก่อนหน้า:

commandA file && commandB !:1 && ...

ไม่ใช่สิ่งที่ฉันมีในใจ แต่เป็นทางเลือกที่น่าสนใจ
Zaid

เกิดอะไรขึ้นกับคำตอบนี้?
Chris

นี่มันเจ๋งจริงๆ! มีวิธีที่จะไม่นิยามตัวแปรใหม่หรือไม่?
ผู้ใช้

@user ฉันได้เพิ่มทางเลือก
maxschlepzig


2

คุณสามารถใช้ xargs เพื่อสร้างบรรทัดคำสั่งเช่น:

echo file | xargs -i -- echo ls -l {}\; wc -l {}

เพียงท่อด้านบนเป็นทุบตีเพื่อเรียกใช้:

echo file | xargs -i -- echo ls -l {}\; wc -l {} | bash

การขยายตัวอย่างไปยังไฟล์ * .c ทั้งหมดในไดเร็กทอรีปัจจุบัน (การหลีกเลี่ยงlsที่นี่เพื่อป้องกันการทดแทนเชลล์นามแฝง):

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash

ใช้สิ่งนี้เพื่อรับรายชื่อของไฟล์ทั้งหมดที่มีอยู่ในไดเรกทอรีที่ชื่อเหมือน "enums": find . -name "*enums*" | xargs -i echo -e echo {}\; ls -lh {}\; echo -e '\n\n' | bash
Matt Lachman

1

ฉันจะไม่ลงคะแนนให้ตัวเอง มันโง่และอันตราย แต่เพียงเพื่อประโยชน์ในการแสดงวิธีการทำสิ่งนี้มี:

for cmd in "commandA" "commandB" "perl -ne '...'" ; do eval $cmd file ; done

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