หากต้องการวนซ้ำชื่อรายการไฟล์ที่มีหนึ่งชื่อต่อบรรทัดคุณมีความเป็นไปได้หลายประการ:
ใช้การทดแทนคำสั่งเพื่อทำงานไฟล์ลงในรายการชื่อไฟล์ภายในเชลล์ คุณต้องใช้ความระมัดระวังเนื่องจากคุณไม่สามารถใส่การทดแทนคำสั่งในเครื่องหมายคำพูดคู่เนื่องจากผลลัพธ์ของการทดแทนคำสั่งจะต้องแยกเป็นคำ คุณต้องปิด globbing และตั้งค่าIFS
ให้แบ่งคำในบรรทัดใหม่เท่านั้น
set -f; IFS='
'
scp -- $(…) remote.example.com:
ใช้read
บิวด์อินเพื่อประมวลผลชื่อไฟล์ในลูป คุณต้องระวังอีกครั้งเพราะread
ปฏิบัติกับเครื่องหมายแบ็กสแลชและ$IFS
อักขระเป็นพิเศษ
… | while IFS= read -r x; do scp -- "$x" remote.example.com: done
คุณสามารถใช้ GNU xargs ได้ แต่คุณต้องเหยียบอย่างระมัดระวังเพราะ xargs ต้องการอินพุตในรูปแบบที่ยกมาอย่างผิดปกติ คุณต้องผ่านการเลือกที่จะเลือกอย่างชัดเจนขึ้นบรรทัดใหม่เป็นตัวคั่นการป้อนข้อมูลและปิดพฤติกรรมพิเศษของช่องว่างและ-d '\n'
\'"
… | xargs -d '\n' -I {} scp {} remote.example.com:
ข้อได้เปรียบเพียงอย่างเดียวของxargs
มันคือมันสามารถจัดกลุ่มหลาย ๆ อาร์กิวเมนต์บนหนึ่งการเรียกใช้จนถึงขีดจำกัดความยาวบรรทัดคำสั่ง แต่ใช้ได้เฉพาะถ้าอาร์กิวเมนต์ถูกส่งผ่านไปยังคำสั่งล่าสุด คุณสามารถทำได้โดยผ่านการโทรศัพท์ระหว่างกลางไปถึงsh
แต่ก็ไม่ค่อยคุ้มกับปัญหา
… | xargs -d '\n' sh -c 'scp -- "$@" "$0"' remote.example.com:
วิธีที่ง่ายกว่าในการใช้xargs
คือรับรายการที่คั่นด้วย null แทนการขึ้นบรรทัดใหม่ สิ่งนี้ต้องการ-0
ตัวเลือกซึ่งรองรับโดย GNU xargs และ * BSD ล่าสุด ดังที่กล่าวข้างต้นการผลักข้อโต้แย้งไปสู่ตำแหน่งที่ไม่ใช่ครั้งสุดท้ายนั้นจำเป็นต้องใช้งานสักหน่อย
… | tr '\n' '\0' | xargs -0 sh -c 'scp -- "$@" "$0"' remote.example.com:
…
ส่วนหนึ่งจะเป็นgrep NAME_REGEXP /path/to/filenames.list
ถ้าคุณหมายถึงการกรองชื่อไฟล์ด้วยสีหน้าปกติ หากคุณต้องการกรองเนื้อหาไฟล์ให้ใช้หนึ่งในเทคนิคด้านบนเพื่อป้อนชื่อไฟล์grep
เช่น
set -f; IFS='
'
scp -- $(grep -l CONTENT_REGEXP -- $(cat /path/to/filenames.list)) \
remote.example.com:
ความเป็นไปได้อีกอย่างที่เลี่ยงผ่านปัญหาเชลล์คือการใช้rsync
และ--files-from
ตัวเลือก สมมติว่าชื่อไฟล์นั้นสัมพันธ์กับไดเรกทอรีปัจจุบัน:
grep NAME_REGEXP /path/to/filenames.list |
rsync -a --files-from - . remote.example.com: