0

Как извлечь определенный элемент из массива в BASH?

7

Я создаю свой массив в bash следующим образом:

while read line
do
   myarr[$index]=$line
   index=$(($index+1))
done < lines.txt

Файл "lines.txt" состоит из следующих строк:

hello big world!
how are you
where am I

После создания массива ${myarr[@]} я могу легко получить доступ к каждому элементу (строке) в этом массиве, выполнив следующую команду:

echo ${myarr[2]}

Но что, если я хочу извлечь только слово world!? Возможно ли извлечь world! из первого элемента массива myarr? Более того, возможно ли извлечь любое последнее слово из элемента массива myarr?

Я знаю, что в Python можно сделать myarr[0][-1] и это сработает, как насчет bash?

3 ответ(ов)

0

Это один из многих способов:

set ${myarr[2]}
echo $3

В этом примере мы используем команду set, чтобы установить позиционные параметры в Bash. Когда вы вызываете set ${myarr[2]}, вы берёте элементы из массива myarr, начиная с третьего элемента (индекса 2) и устанавливаете их как позиционные параметры. После этого, вызов echo $3 выводит третий позиционный параметр, который теперь соответствует элементу массива myarr[2].

Убедитесь, что массив myarr был инициализирован заранее, чтобы избежать ошибок.

0

Вы можете извлекать слова из строки (каждый элемент массива - это и есть строка) с помощью модификаторов в расширении переменных: # (удалить префикс), ## (удалить префикс, жадный), % (удалить суффикс) и %% (удалить суффикс, жадный).

Вот пример, как это работает:

$ myarr=('hello big world!' 'how are you' 'where am I')
$ echo "${myarr[0]}"      # Полный первый элемент массива
hello big world!
$ echo "${myarr[0]##* }"  # Чтобы получить последнее слово, удаляем префикс до последнего пробела
world!
$ echo "${myarr[0]%% *}"  # Чтобы получить первое слово, удаляем суффикс, начиная с первого пробела
hello
$ tmp="${myarr[0]#* }"    # Второе слово сложнее; сначала удаляем до первого пробела...
$ echo "${tmp%% *}"       # ...затем получаем первое слово из оставшегося
big
$ tmp="${myarr[0]#* * }"  # Третье слово (которое может быть и не последним)? Удаляем до второго пробела...
$ echo "${tmp%% *}"       # ...а затем снова получаем первое слово
world!

Как вы можете видеть, это может стать довольно изощренным, но в какой-то момент предложение @chepner превратить строку в массив становится гораздо проще. Также формулы, которые я предлагаю для извлечения второго и последующих слов, немного хрупкие: если вы используете мою формулу для извлечения третьего слова из строки, в которой только два слова, первое обрезание не сработает, и в результате будет напечатано первое (!) слово вместо пустого. Кроме того, если в строке есть два пробела подряд, это будет восприниматься как слово нулевой длины с пробелами по обе стороны...

Кстати, при создании массива я считаю немного более чистым использовать +=(newelement), чем явно отслеживать индекс массива:

myarr=()
while read line; do
    myarr+=("$line")
done < lines.txt
0

Чтобы вывести конкретный элемент из массива по индексу, можно использовать следующую команду:

echo ${my_array[2]}

Если вы хотите вывести все элементы массива, используйте следующий цикл:

for i in "${my_array[@]}"
do
    echo $i
done

Таким образом, для доступа к отдельным элементам массива используется индекс, а для перебора всех элементов — цикл for.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь