У меня есть скрипт bash, который разбивает массив bash на пары и сопоставляет любой элемент;
declare -a arr=(
"apple" "fruit"
"cabbage" "vegetables"
)
for ((i=0; i<${#arr[@]}; i+=2)); do
echo "${arr[i]} ${arr[i+1]}"
done
Итак, когда вы запускаете этот скрипт, он выводит каждые 2 элемента из массива, например:
# bash script
apple fruit
cabbage vegetables
и я также могу выбрать любой элемент с помощью ${arr[i+@]}.
Теперь я пытаюсь прочитать этот массив из отдельного текстового файла, а не внутри скрипта, так как в будущем я буду манипулировать этим массивом.
До сих пор я пробовал этот метод, который поначалу выглядел довольно многообещающе, но совсем не работал;
filename='stuff.log'
filelines=`cat $filename`
for line in $filelines ; do
props=($line)
echo "${props[0]} ${props[1]}"
done
который должен был вывести в консоль приведенный ниже контент (в основном то же самое, что и первый скрипт, где массив находится внутри скрипта), предположительно, но вместо этого он ничего не вернул.
# bash script
apple fruit
cabbage vegetables
И внутри stuff.log;
"apple" "fruit"
"cabbage" "vegetables"
Как я могу в основном прочитать массив из отдельного файла для первого скрипта, а также иметь возможность манипулировать содержимым файла массива в будущем?
Почитаю, спасибо за это! действительно помогает самосовершенствоваться. оценил.
прежде чем вы погрузитесь в манипуляции с текстом в bash, я предлагаю вам прочитать некоторые основы awk, чтобы справиться с вашими будущими проблемами.



Я думаю, если вы доверяете своему вкладу, вы можете сделать:
IFS=' \n' eval props=($(<stuff.log))
Eval — это зло, и оно предназначено для удаления начального и конечного ". И он будет правильно анализировать элементы с пробелами в них. Мы можем сделать немного безопаснее, прочитав файл в массив, а затем удалив начальный и конечный ":
IFS=' \n' props=($(<stuff.log))
IFS='\n' props=($(printf "%s\n" "${props[@]}" | sed 's/^"//;s/"$//'))
В любом случае, я бы не решился использовать такой метод в производственном коде. Было бы лучше написать полноценный синтаксический анализатор, учитывающий " и считывающий ввод char за char.
Если вы хотите прочитать файл в массив, используйте команды mapfile или readarray (это одна и та же команда).
Спасибо за ваш ответ. Кажется, я не мог понять, что с этим делать. Извините, я действительно новичок в bash. Можете ли вы привести мне рабочий пример, если вы не возражаете?
О, я вижу. И кажется, что я могу выбрать любой элемент, например echo "${props[i+2]}", однако это идет в порядке, например, для элемента 50th я должен использовать echo "${props[I+50]}", верно? И так как у меня будет около 120 строк в файле массива и 3 столбца для каждой строки, будет ли это удобно в использовании? Я думал о чем-то вроде чтения каждой строки с 3 приращениями и выбора каждого элемента каждой строки с помощью ${props[i]}, ${props[I+1]} и ${props[i+2]}, поэтому я могу использовать только i0, 1 and 2 вместо использования i+120 для первого элемента 120-й строки.
Есть много онлайн-страниц, объясняющих, как работают массивы в bash. Чтобы получить доступ к 50-му элементу в массиве props, используйте ${props[49]}. Если i является целым числом, например. i=5, затем ${props[i + 1]} сначала расширяет i+1 до 5+1, вызывает epxr для его вычисления (результат = 6), а затем вызывает ${props[6]} после расширения. i have 120 lines ... 3 columns - затем выберите соответствующую абстракцию. В Bash нет двумерных массивов. Я бы не советовал хранить что-либо в массивах bash, они медленные, делайте весь необходимый вам парсинг стандартными unix-инструментами (comm, join, awk, sed, cut и т.д.)
Да, может быть, я должен использовать их. Спасибо.