ครั้งแรกของทั้งหมดไม่ได้ใช้ls
ออกเป็นรายชื่อไฟล์ find
ใช้การขยายตัวของเปลือกหรือ ดูด้านล่างสำหรับผลที่อาจเกิดขึ้นจากการใช้ls + xargsในทางที่ผิดและตัวอย่างของการxargs
ใช้งานที่เหมาะสม
1. วิธีง่ายๆ: สำหรับลูป
หากคุณต้องการประมวลผลไฟล์ภายใต้A/
การfor
วนรอบแบบง่ายควรจะเพียงพอ:
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1ทำไมไม่ ls | xargs
?
นี่คือตัวอย่างของวิธีการที่สิ่งเลวร้ายอาจเปลี่ยนไปถ้าคุณใช้ls
กับxargs
งาน พิจารณาสถานการณ์สมมติต่อไปนี้:
ก่อนอื่นมาสร้างไฟล์เปล่า:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
ดูไฟล์และพวกเขาไม่มีอะไร:
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
ใช้คำสั่ง magic โดยใช้xargs
:
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
ผลลัพธ์:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
เพื่อให้คุณได้มีการจัดการเพียงเพื่อแทนที่ทั้งสองและmypreciousfile.dat
mypreciousfile.dat.ans
หากมีเนื้อหาใด ๆ ในไฟล์เหล่านั้นแสดงว่าถูกลบไปแล้ว
2. การใช้ xargs
: วิธีที่เหมาะสมด้วย find
หากคุณต้องการที่จะยืนยันการใช้xargs
ให้ใช้-0
(ชื่อที่ลงท้ายด้วย null):
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
สังเกตเห็นสองสิ่ง:
- วิธีนี้คุณจะสร้างไฟล์โดย
.dat.ans
สิ้นสุด
- สิ่งนี้จะแตกถ้าชื่อไฟล์บางอันมีเครื่องหมายคำพูด (
"
)
ปัญหาทั้งสองสามารถแก้ไขได้ด้วยวิธีต่าง ๆ ของการเรียกใช้เชลล์:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. ทั้งหมดทำภายใน find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
นี้อีกครั้งผลิตไฟล์และจะทำลายถ้าชื่อไฟล์ประกอบด้วย.dat.ans
"
หากต้องการทำสิ่งนั้นให้ใช้bash
และเปลี่ยนวิธีการเรียกใช้:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;