เก็บเอาต์พุตของคำสั่งลงในอาร์เรย์


23

นี่คือคำสั่ง: pdc status -a 2>&1 | grep 'okay'มันให้ผลลัพธ์ต่อไปนี้

[okay     ]: you are currently listening: 33
[okay     ]: you are currently listening: 22
[okay     ]: you are currently listening: 11

ฉันได้เขียนคำสั่งนี้ในไฟล์ shell scrip แต่ฉันต้องการเก็บผลลัพธ์ของคำสั่งนี้ลงในอาร์เรย์สำหรับการประมวลผลบางอย่างในแต่ละค่าดัชนีในอาร์เรย์

ฉันจะเก็บผลลัพธ์ของคำสั่งนี้ลงในอาร์เรย์ได้อย่างไร

คำตอบ:


24

หากคุณต้องการตัวเลขที่ท้ายของแต่ละบรรทัด:

numbers=( $(pdc ... | grep -oP 'okay.+?\K\d+$') )

หากคุณต้องการเก็บแต่ละบรรทัดลงในอาร์เรย์

mapfile -t lines < <(pdc ...)

ในการดึงข้อมูลจากอาร์เรย์:

for (( i=0; i<${#numbers[@]}; i++ )); do echo ${numbers[i]}; done
echo
printf "%s\n" "${lines[@]}"
33
22
11

[okay   ]: you are currently listening: 33
[okay   ]: you are currently listening: 22
[okay   ]: you are currently listening: 11

1
ข้อผิดพลาดของไวยากรณ์: การเปลี่ยนเส้นทางที่ไม่คาดคิดเมื่อฉันใช้mapfile -t array < <(grep.....)
Sachith Muhandiram

คุณใช้ทุบตีหรือเปลือกอื่น ๆ ?
เกล็นแจ็

20

ก่อนอื่นคุณไม่จำเป็นต้องมีอาเรย์ในการประมวลผลเอาต์พุตบรรทัดต่อบรรทัดที่คุณสามารถทำได้:

pdc status -a 2>&1 | grep 'okay' | while read line; do somecommand "$line"; done

หากคุณต้องการอาเรย์นั้นเกล็นแจ็คแมนได้ให้วิธีที่ดีที่สุดในการทำมัน แต่นี่เป็นวิธีการอื่น:

#!/bin/bash
IFS=$'\n'
array=($(pdc status -a 2>&1 | grep 'okay'))

คำอธิบาย:

  • $IFS=$'\n': $IFSเป็นตัวคั่นฟิลด์อินพุตของ bash โดยตั้งเป็นอักขระบรรทัดใหม่เท่านั้น ( \n) ตรวจสอบให้แน่ใจว่าบรรทัดเอาต์พุตของคุณจะไม่ถูกแยกบนช่องว่างเพื่อให้คุณสามารถบันทึกแต่ละบรรทัดเป็นองค์ประกอบอาร์เรย์แยก หากไม่มีสิ่งนี้เอาต์พุตของคำสั่งของคุณแต่ละคำจะเป็นองค์ประกอบที่แตกต่างกัน

    ขึ้นอยู่กับสิ่งที่คุณต้องการทำมันอาจเป็นความคิดที่ดีที่จะบันทึกค่าเก่า$IFSและคืนค่าหลังจากอ่านอาร์เรย์แล้ว:

    oldifs="$IFS"
    IFS=$'\n'
    array=($(echo -e "foo bar\nbaz bar"))
    IFS="$oldifs"
  • $(command): สิ่งนี้เรียกว่าการทดแทนคำสั่งและอนุญาตให้คุณบันทึกผลลัพธ์ของคำสั่งในตัวแปร มีสองวิธีในการทำสิ่งนี้:

    var=$(command)

    และ

    var=`command`

    ในสองเรื่อง$()นี้ดีกว่าเพราะ:

    • มันสามารถจัดการกับคำสั่งที่ซ้อนกัน:

      var=$(command1 $(command 2))

      ตัวอย่างเช่น var=$(cat $(find ~/))

    • มันมีปัญหาน้อยกว่ามากเกี่ยวกับการอ้างอิงและผลลัพธ์ในไวยากรณ์ที่สะอาดกว่า ดูที่นี่สำหรับข้อมูลเพิ่มเติม


6

อีกวิธีที่ใช้งานง่ายยิ่งขึ้นโดยใช้readarraybuiltin (ดูhelp -m readarray):

readarray -t array <<< "$(pdc status -a 2>&1 | grep 'okay')"

ถัดไปเพื่อพิมพ์องค์ประกอบอาร์เรย์สมมติว่าองค์ประกอบที่สองคุณสามารถใช้:

echo "${array[1]}"

หากต้องการพิมพ์องค์ประกอบอาร์เรย์ทั้งหมดในบรรทัดแยกคุณสามารถใช้:

printf -- "%s\n" "${array[@]}"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.