วนซ้ำกับสตริงหลายบรรทัดที่เก็บอยู่ในตัวแปร


17

ฉันอ่านว่ามันไม่ดีที่จะเขียนสิ่งต่าง ๆ เช่นfor line in $(command)วิธีที่ถูกต้องดูเหมือนจะเป็นแทน:

command | while IFS= read -r line; do echo $line; done

มันใช้งานได้ดี แต่ถ้าสิ่งที่ฉันต้องการทำซ้ำคือเนื้อหาของตัวแปรไม่ใช่ผลลัพธ์โดยตรงของคำสั่ง

ตัวอย่างเช่นสมมติว่าคุณสร้างไฟล์ต่อไปนี้quickfox:

The quick brown
foxjumps\ over -
the
lazy ,
dog.

ฉันอยากทำสิ่งนี้:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect

คำตอบ:


19

ในเชลล์สมัยใหม่เช่น bash และ zsh คุณมีตัวเปลี่ยนเส้นทางที่มีประโยชน์มาก `<<< 'ที่ยอมรับสตริงเป็นอินพุต ดังนั้นคุณจะทำ

while IFS= read -r line ; do echo $line; done <<< "$variable"

มิฉะนั้นคุณสามารถทำได้

echo "$variable" | while IFS= read -r line ; do echo $line; done

ขออภัยฉันควรคิดเกี่ยวกับการสะท้อนเนื้อหาของหลักสูตร แต่ขอบคุณสำหรับคำตอบด่วน!
Sheljohn

1
คุณต้อง$variableใส่เครื่องหมายอัญประกาศคู่เมื่อคุณใช้งานมิฉะนั้นการwhileวนซ้ำจะได้รับอินพุตเพียงบรรทัดเดียว ดูตัวอย่างเช่นความแตกต่างในการส่งออกระหว่างecho $variableVS echo "$variable"หรือเทียบcat <<< $variable cat <<< "$variable"
cas

@cas ที่จริงแล้วมันขึ้นอยู่กับว่าอะไรอยู่ในตัวแปร $ ในกรณีที่นำเสนอโดย OP ("ตัวแปร = $ (cat quickfox)") มันทำงานโดยไม่มีเครื่องหมายอัญประกาศเพิ่มเติม แต่สำหรับกรณีทั่วไปคุณพูดถูก ฉันแก้ไขคำตอบของฉัน ขอบคุณ
lgeorget

variable=$(cat quickfox)ในคำถาม OP ของตัวเองให้ตัวอย่างของสิ่งที่ผมได้พูดคุยเกี่ยวกับ การใช้ที่$variableอยู่ภายในเครื่องหมายคำพูดคู่จะรวมถึงการขึ้นบรรทัดใหม่โดยใช้มันโดยไม่ต้องมีการขึ้นบรรทัดใหม่ที่แปลเป็นช่องว่างโดยเชลล์ หากคุณกำลังอ่านและประมวลผลทีละบรรทัดสิ่งนี้จะสร้างความแตกต่างอย่างมากกับที่ผ่านมาคุณมีอินพุตหลายบรรทัดโดยที่หลังคุณมีอินพุตเพียงบรรทัดเดียว ข้อมูลอินพุตนั้นคล้ายคลึงกันมาก แต่ในทางปฏิบัตินั้นแตกต่างกันอย่างสิ้นเชิงในทั้งสองกรณี
cas

ตัวอย่างเช่น: กับข้อมูลอินพุตนั้นcat <<< "$variable" | wc -lส่งคืน 5. cat <<< $variable | wc -lคืนค่า 1 หากคุณต้องการ / จำเป็นต้องรักษาช่องว่าง (รวมถึงการขึ้นบรรทัดใหม่แท็บช่องว่างเดี่ยวหรือหลายช่องว่าง) ในตัวแปรจากนั้นคุณต้องใส่เครื่องหมายคำพูดสองครั้งเมื่อใช้ พวกเขาทั้งหมดจะถูกเปลี่ยนเป็นช่องว่างเดียวระหว่าง "คำ" แต่ละคำ
cas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.