ดูเหมือนว่าวิธีการที่เป็นที่ยอมรับในการทำเช่นนี้bash
เป็นสิ่งที่ต้องการ
unset args
while IFS= read -r line; do
args+=("$line")
done < file
cmd "${args[@]}"
หรือถ้า bash เวอร์ชันของคุณมีmapfile
:
mapfile -t args < filename
cmd "${args[@]}"
ความแตกต่างเพียงอย่างเดียวที่ฉันสามารถหาได้ระหว่าง mapfile และลูปแบบอ่านขณะเปรียบเทียบกับแบบหนึ่งบรรทัด
(set -f; IFS=$'\n'; cmd $(<file))
คืออดีตจะแปลงบรรทัดว่างเป็นอาร์กิวเมนต์ว่างเปล่าในขณะที่หนึ่งซับจะไม่สนใจบรรทัดว่าง ในกรณีนี้พฤติกรรมแบบหนึ่งซับคือสิ่งที่ฉันต้องการอยู่แล้วดังนั้นโบนัสสองเท่าของคอมแพค
ฉันจะใช้IFS=$'\n' cmd $(<file)
แต่มันใช้งานไม่ได้เพราะ$(<file)
ถูกตีความให้เป็นบรรทัดคำสั่งก่อนที่IFS=$'\n'
จะมีผล
แม้ว่ามันจะไม่ทำงานในกรณีของฉัน แต่ตอนนี้ฉันได้เรียนรู้ว่ามีเครื่องมือมากมายที่สนับสนุนการยกเลิกบรรทัดด้วยnull (\000)
แทนที่จะnewline (\n)
ทำให้ง่ายกว่านี้เมื่อพูดถึงชื่อไฟล์ซึ่งเป็นแหล่งที่มาทั่วไปของสถานการณ์เหล่านี้ :
find / -name '*.config' -print0 | xargs -0 md5
ฟีดรายการชื่อไฟล์ที่ผ่านการรับรองโดยสมบูรณ์เป็นอาร์กิวเมนต์สำหรับ md5 โดยไม่มีการวนซ้ำหรือการสอดแทรกหรืออะไรก็ตาม ที่นำไปสู่การแก้ปัญหาที่ไม่ได้อยู่ในตัว
tr "\n" "\000" <file | xargs -0 cmd
ถึงแม้ว่าสิ่งนี้จะละเว้นบรรทัดว่างแม้ว่ามันจะจับเส้นที่มีพื้นที่ว่างเท่านั้น