ครั้งแรกของทั้งหมดไม่ได้ใช้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"' {} \;