การพิมพ์อาเรย์ไปยังไฟล์ด้วยองค์ประกอบของอาเรย์ในบรรทัดใหม่ในทุบตี


13

ฉันพยายามเนื้อหาของอาเรย์เป็นไฟล์ที่มีองค์ประกอบของอาเรย์ในแต่ละบรรทัดในบรรทัดใหม่ในไฟล์

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


เนื้อหาของ mtches คือ "qwe" และ "asd" แต่sample1.txtไฟล์มีqwe asdอยู่ในบรรทัดเดียว ทำไมการไม่ใช้ค่า IFS ในภาพ

คำตอบ:


17

คุณควรใช้printfแทนecho :

printf "%s\n" "${mtches[@]}"

หากmtchesว่างเปล่าที่จะยังคงส่งออกหนึ่งบรรทัดว่าง เพื่อบัญชีที่:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

ในbash(และกระสุน POSIX) คุณมักจะใช้อาร์เรย์พารามิเตอร์ตำแหน่ง"$@"แทนแทนที่จะเป็น"$*"เว้นแต่คุณจะมีเหตุผลพิเศษ นอกจากนี้ยังเป็นจริงในเชลล์ที่สนับสนุนอาร์เรย์ปกติจาก man bash - อาเรย์ส่วน :

องค์ประกอบใด ๆ ของอาเรย์อาจถูกอ้างอิงโดยใช้ $ {name [subscript]} การจัดฟันจำเป็นต้องหลีกเลี่ยงความขัดแย้งกับตัวดำเนินการขยายชื่อไฟล์ของเชลล์ หากตัวห้อยคือ '@' หรือ '*' คำนั้นจะขยายไปยังสมาชิกทั้งหมดของชื่ออาเรย์ ตัวห้อยเหล่านี้แตกต่างกันเฉพาะเมื่อคำนั้นปรากฏภายในเครื่องหมายคำพูดคู่ หากคำนี้เป็นเครื่องหมายคำพูดสองครั้ง $ {name [*]} จะขยายเป็นคำเดียวโดยมีค่าของสมาชิกอาเรย์แต่ละตัวคั่นด้วยอักขระตัวแรกของตัวแปร IFS และ $ {name [@]} จะขยายแต่ละองค์ประกอบของชื่อ เป็นคำที่แยกกัน เมื่อไม่มีสมาชิกอาเรย์ $ {name [@]} จะไม่ขยายสิ่งใดเลย หากการขยายที่ยกมาสองครั้งเกิดขึ้นภายในคำการขยายตัวของพารามิเตอร์แรกจะถูกรวมเข้ากับส่วนเริ่มต้นของคำเดิมและการขยายตัวของพารามิเตอร์สุดท้ายจะรวมกับส่วนสุดท้ายของคำเดิม

ใช้"${array[*]}"เมื่อคุณต้องการรวมองค์ประกอบอาร์เรย์ทั้งหมดเข้ากับสตริงเท่านั้น


นั่นทำให้ความแตกต่างได้อย่างไร
Ashwin


7

คุณต้องการใช้${mtches[*]}แทน

เมื่อคุณใช้"${mtches[@]}"มันไม่สำคัญว่าค่า$IFSคือ bash จะแบ่งอาร์เรย์ออกเป็นหลายอาร์กิวเมนต์ \nสิ่งที่คุณต้องการคืออาร์กิวเมนต์เดียวกับแต่ละองค์ประกอบอาร์เรย์เข้าร่วมโดย ${mtches[*]}สำเร็จนี้

เช่นเดียวกับการตั้งค่าชั่วคราว$IFSคุณสามารถทำ:

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

จากนั้นคุณไม่ต้องกังวลกับการตั้งค่ากลับ


pubs.opengroup.org/onlinepubs/9699919799/utilities/… <- การอ้างอิง POSIX (สิ่งนี้ไม่สามารถใช้ได้กับการทุบตีเท่านั้น)
Mat

หรือใช้printf...
jasonwryan

2

ใช้สำหรับ :

for each in "${alpha[@]}"
do
  echo "$each"
done

ใช้ประวัติศาสตร์ ; โปรดทราบว่าสิ่งนี้จะล้มเหลวหากค่าของคุณมี!:

history -p "${alpha[@]}"

ใช้basename ; โปรดทราบว่าสิ่งนี้จะล้มเหลวหากค่าของคุณมี/:

basename -a "${alpha[@]}"

ใช้shuf ; โปรดทราบว่าผลลัพธ์อาจไม่ออกมาตามลำดับ:

shuf -e "${alpha[@]}"

1
for ENTRY in ${ARRAY[@]}; do
    echo $ENTRY
done > outfile

ดีและอ่านได้และไม่ได้แปลว่ายุ่งกับ IFS นอกจากนี้ยังหมายความว่าคุณสามารถกำหนดการจัดการแต่ละบรรทัดได้เอง


1
แต่ที่ไม่ถูกต้องในขณะที่คุณกำลังใช้echoซึ่งไม่สามารถนำมาใช้สำหรับเนื้อหาโดยพลการและไม่ลืมที่จะพูดตัวแปรของคุณ รุ่นที่ดีขึ้นเล็กน้อยถูกโพสต์แล้วโดย StevenPenny
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.