Як видалити новий рядок, доданий 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

Явний неявний символ нового рядка додається неreadarray вбудованим, а значком here-string ( <<<) bash, див. Чому баш тут-рядка додає проміжний знак нового рядка? . Ви можете позбутися цього, надрукувавши рядок без нового рядка, використовуючи printfта прочитавши його за допомогою технології заміни процесу< <()

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

буде належним чином генерувати зараз

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

3
Оце Так! Я б цього ніколи не знайшов. Дякую
користувач1156544

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).

Зауважте, що незважаючи на Sin IFS(що означає роздільник ), він працює так само, як і readarrayв a,,b,розділеному на "a", ""і "b"тільки.

Для справжнього оператора розщеплення ви можете використовувати zshзамість цього:

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

( @подвійні лапки для збереження порожніх елементів).


Запис readarray <<< "$string"у файл tempp, а потім видаляє його замість використання пам'яті?
користувач1156544

@ user1156544 Так.
mosvy

Як я можу зробити щось подібне до вашої останньої команди в bash? Я використовую bash 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(перший аргумент функції).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.