ทำไม bash จึงลบ \ n เป็น $ (ไฟล์ cat)


24

หากฉันมีไฟล์input.txtที่มี:

hello
world
!

จากนั้นการดำเนินการคำสั่ง bash echo $(cat input.txt)จะแสดงผลลัพธ์นี้:

hello world !

ทำไมและฉันจะแก้ไขมันเพื่อส่งออกสิ่งที่อยู่ในไฟล์ว่ามันเป็นอย่างไรในไฟล์?

คำตอบ:


32

ถ้าคุณใช้

echo "$(cat input.txt)"

มันจะทำงานอย่างถูกต้อง

อาจอินพุตของ echo ถูกคั่นด้วยการขึ้นบรรทัดใหม่และมันจะจัดการเป็นคำสั่งแยกดังนั้นผลลัพธ์จะไม่มีการขึ้นบรรทัดใหม่


ดี! ดังนั้นความแตกต่าง (ถ้ามี) ระหว่าง $ () และ backticks คืออะไร (ขออภัยหากนี่เป็นวงสัมผัสมากเกินไป)
Chan-Ho Suh

พวกเขาจะเทียบเท่ายกเว้นความจริงที่ว่า $ (... ) ง่ายต่อการซ้อน ในทั้งสองกรณีหากคุณไม่ได้อ้างอิงผลลัพธ์ผลลัพธ์นั้นจะถูกโทเค็นเป็นหลายอาร์กิวเมนต์ในพื้นที่สีขาว
James Henstridge

3
แต่อักขระขึ้นบรรทัดใหม่สุดท้ายจะถูกละเว้นแม้จะอยู่ในเครื่องหมายคำพูดคู่ ในทางตรงกันข้ามผู้ประกอบการ backtick ของ Perl ขยายไปยังเอาต์พุตทั้งหมดของคำสั่งรวมถึงบรรทัดใหม่ทั้งหมด
Keith Thompson

6
@KeithThompson ใช่การแทนที่คำสั่งจะลบบรรทัดใหม่ต่อท้ายทั้งหมดออกจากเอาต์พุต ที่มีข้อได้เปรียบของecho "$(date) something"การแยกบรรทัดใหม่ออกมาจากเอาท์พุทของวันที่ทำให้สะท้อนเอาท์พุทวันที่และ "บางสิ่งบางอย่าง" ในบรรทัดเดียวกัน หากคุณต้องการจัดเก็บไฟล์หรือเอาต์พุตคำสั่ง "ตามสภาพ" ให้ใช้ mapfile ( help mapfile) read -rd ''หรือ a-while แบบ read-loop
geirha

ขอบคุณทุกคน :-) ฉันได้เรียนรู้บางสิ่งจากความคิดเห็นทุกข้อที่นี่!
Chan-Ho Suh

2

อ้างถึงจากหน้าคู่มือทุบตีส่วนCommand Substitution:

บรรทัดใหม่ที่ฝังจะไม่ถูกลบ แต่อาจถูกลบระหว่างการแยกคำ

เพิ่มเติมเล็กน้อยในส่วนเดียวกัน:

หากการแทนที่ปรากฏภายในเครื่องหมายคำพูดคู่การแยกคำและการขยายชื่อพา ธ จะไม่ถูกดำเนินการกับผลลัพธ์

นั่นเป็นเหตุผลที่echo "$(cat /etc/passwd)" ทำงาน

นอกจากนี้ควรทราบว่าการแทนที่คำสั่งนั้นด้วยข้อมูลจำเพาะ POSIXจะลบบรรทัดใหม่ที่ต่อท้าย:

$ echo "$(printf "one\ntwo\n\n\n")"
one
two

ดังนั้นการส่งออกไฟล์ผ่าน$(cat file.txt)อาจทำให้สูญเสียการขึ้นบรรทัดใหม่และอาจเป็นปัญหาหากความสมบูรณ์ของไฟล์ทั้งหมดมีความสำคัญ


2

คุณสามารถเก็บบรรทัดใหม่ได้เช่นโดยการตั้งค่า IFS ให้ว่าง:

$ IFS=
$ a=$(cat links.txt)
$ echo "$a"
link1
link2
link3
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.