массив bash с пробелом в элементе [closed]

#!/bin/bash
echo "Enter username: "
read username
useradd "$username"
echo "temp4now" | passwd --stdin "$username"
chage -d 0 "$username"
1
05.12.2018, 01:25
3 ответа

Единственнымgrep-решением является

grep gis aaa | grep -o '^[^"]*"[^"]*"' | grep -o '"[^"]*"$'

Первый grepтакой же, как у вас в вопросе. Очевидно, он выбирает строки, содержащиеgis(в любом месте строки ). Второй grep,

grep -o '^[^"]*"[^"]*"'

соответствует всему, начиная с (, включая ). первая строка в кавычках в строке (, т. е. столбцы с 1 по 4 ), и из-за опции-oвыводит только этих слов. Третий grep,

grep -o '"[^"]*"$'

соответствует последнему слову строки в кавычках в строке (, что на данный момент является столбцом 4 исходной строки )и выводит только эту строку.


П.С. Если в вашем файле есть одна вкладка между каждой парой столбцов, и значения не содержат табуляции, простой способ получить четвертый столбец —

awk -F'\t' '/gis/ { print $4 }' aaa
0
27.01.2020, 23:31

Проблема коренится в этой строке:

 r=( $(grep gis aaa) )

Как вы сразу увидите, если попробуете:

 printf '<%s>\n' $(grep gis aaa)

Который разбивается на символы внутри "$IFS" (пробел, табуляция, новая строка по умолчанию ).

А предоставляет значения из файла для подстановки. Какие будут преобразованы некоторые *, ?и […](, какие из них будут зависеть от списка файлов на вашем pwd и состояния нескольких опций оболочки ).

Одним из (нерекомендуемых )решений является изменение IFSна разделительный символ и отключение подстановки для разделения:

 IFS=$'\n'; set -f; r=( $(grep gis aaa) )

Но более простое решение — использовать то, что уже предоставляет оболочка:

readarray -t r <(grep gis aaa) 

Это будет разбито на новые строки (при условии, что в именах путей нет новых строк ).

Затем, чтобы избежать повторного разбиения каждой строки, чтобы получить каждую часть, которая может подвергнуть строку разбиению и подстановке пробелов, давайте удалим начальную и конечную части строк.

Если из каждой строки убрать все от начала до"/(двойной кавычки и косой черты )и все от"(двойной кавычки и пробела )до конца, то получим чистый путь:

 #!/bin/bash

 function nodatechk() {
    for l do
        l="/${l#*\"/}"                # Remove leading text up to `"/`
        l=${l%\" *}                   # Remove trailing text from `" `
        printf '%s\n' "$l"
    done
 }

 readarray -t r < <(grep gis aaa)

 nodatechk "${r[@]}"
4
27.01.2020, 23:31

Я прочитал этот пост и решил проблему с помощью 'eval'. Поэтому изменил эту строку:

r=( $(grep gis aaa) )

от

до

eval r="( $(grep gis aaa) )"

-1
27.01.2020, 23:31

Теги

Похожие вопросы