วิธีลบบรรทัดใหม่ที่เพิ่มโดย readarray เมื่อใช้ตัวคั่น?


10
VAR=a,b,c,d
# VAR=$(echo $VAR|tr -d '\n')
echo "[$VAR]"
readarray -td, ARR<<< "$VAR"
declare -p ARR

ผลลัพธ์:

[a,b,c,d]
declare -a ARR=([0]="a" [1]="b" [2]="c" [3]=$'d\n')

ฉันจะบอกreadarrayไม่ให้เพิ่มบรรทัดใหม่สุดท้ายได้\nอย่างไร ความหมายของ$สัญลักษณ์ล่าสุดคืออะไร?


คำตอบ:


13

อักขระขึ้นบรรทัดใหม่ที่แฝงตัวไม่ได้ถูกเพิ่มโดยreadarraybuiltin แต่โดย here-string ( <<<) ของbashให้ดูที่ทำไม bash here-string จึงเพิ่มอักขระขึ้นบรรทัดใหม่ที่ต่อท้าย . คุณสามารถกำจัดมันได้โดยการพิมพ์สตริงโดยไม่ต้องใช้บรรทัดใหม่printfและอ่านมันผ่านเทคนิคการทดแทนกระบวนการ< <()

readarray -td, ARR < <(printf '%s' "$VAR")
declare -p ARR

จะสร้างอย่างถูกต้องในขณะนี้

declare -a ARR=([0]="a" [1]="b" [2]="c" [3]="d")

3
ว้าว! ฉันจะไม่พบสิ่งนี้ ขอบคุณ
user1156544

4

คุณสามารถใช้ split + glob (เกิดอะไรขึ้นเมื่อคุณปล่อยส่วนขยายโดยไม่ระบุในบริบทรายการ) มันได้รับในทางของเราเวลาส่วนใหญ่มันจะเป็นความอัปยศที่จะไม่ใช้เมื่อเราต้องการมัน:

IFS=,
set -o noglob

ARR=($VAR) # split+glob with glob disabled, and split using , as delimiter

นั่นเป็นเรื่องที่ซับซ้อนน้อยกว่าการเขียนไฟล์ชั่วคราวแล้วโทรหาreadarrayมันเหมือนในreadarray <<< "$string"แนวทาง (โปรดทราบว่าreadarray -dต้องใช้เวอร์ชันล่าสุดของbash)

หมายเหตุว่าแม้จะมีSในIFS(ซึ่งหมายถึงคั่น ) ที่ทำงานเช่นเดียวกับreadarrayในการที่a,,b,จะแบ่งออกเป็น"a", ""และ"b"เพียง

สำหรับผู้ดำเนินการแยกที่แท้จริงคุณสามารถใช้zshแทน:

ARR=("${(@s:,:)VAR}")

( @เครื่องหมายคำพูดและคู่เพื่อรักษาองค์ประกอบที่ว่างเปล่า)


readarray <<< "$string"เขียนไปยังแฟ้ม tempp แล้วลบมันแทนการใช้หน่วยความจำ?
user1156544

@ user1156544 ใช่
mosvy

ฉันจะทำสิ่งที่คล้ายกับคำสั่งสุดท้ายของคุณในทุบตีได้อย่างไร ฉันใช้ทุบตี 3.3 และพยายามชดเชยการขาดreadarray -d
user1156544

3

คำตอบ @ StéphaneChazelasเวอร์ชันกระป๋อง:

# usage: setarray varname sep string
setarray(){ declare -n a=$1; local IFS=$2 -; set -f; a=($3); }

$ setarray arr , 1,2,3,
$ declare -p arr
declare -a arr=([0]="1" [1]="2" [2]="3")

$ setarray path : "$PATH"
$ setarray ld_preload ': ' "$LD_PRELOAD" # its elements can be separated by either ':' or spaces
...

local -จะทำให้ตัวเลือกเช่นset -f( noglob) ในท้องถิ่นเพื่อฟังก์ชั่นเช่นเดียวกับตัวแปร

declare -n a=$1จะสร้างท้องถิ่นตัวแปรaเป็นชื่อแทนให้กับตัวแปรโลกตั้งชื่อตาม$1(อาร์กิวเมนต์แรกฟังก์ชั่น)

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