FOR loop: передать 2 переменные из файла одновременно

Это означает, что профиль AppArmor, влияющий на программу / usr / sbin / nmbd , был удален («неограничен») с помощью инструмента apparmor_parser . Это означает, что с этого момента программа будет запускаться без ограничений со стороны AppArmor (до тех пор, пока она снова не будет ограничена - возможно, это произойдет при загрузке, в зависимости от того, как настроена ваша система).

Если вы спрашиваете , почему это происходит, я не знаю. Очевидно, что-то вызывает apparmor_parser -R , но я не знаю, зачем ему это нужно и как именно он вызывается.

0
20.03.2019, 07:04
3 ответа

Вы можете использовать,while read:

echo "title"
while read -r i j
do
    echo total "$i,$j"
done < list
echo "end"

Это даст результат:

title
total AAA,111
total BBB,222
total CCC,333
end
2
28.01.2020, 02:14

Цикл forили whileна самом деле не нужен. Любая из этих awkкоманд будет работать:

awk 'BEGIN {print "title"}
           {print "total",$1","$2}
       END {print "end"}' list

или:

awk 'BEGIN {print "title"}
           {printf "total %s,%s\n", $1, $2}
       END {print "end"}' list

BEGIN{print "title"}печатает слово titleодин раз перед чтением данных в файле.

{print "total",$1","$2}печатает слово total, за которым следует запятая без кавычек, представляющая пробел между значениями в столбцах столбцов, а затем сами столбцы. Этот блок выполняется для каждой входной строки.

END{print "end"}печатает слово endи КОНЕЦ файла. END говорит ему выполнить блок, когда окончательный ввод из файла будет прочитан.

Для второй команды:

Единственная разница:

{printf "total %s,%s\n", $1, $2}

Здесь используется printfвместо print, где первый аргумент определяет формат.

%s,%sговорит ему напечатать значения $1и $2, разделенные запятой, а \nпредставляет новую строку, так что он переходит к следующей строке и печатает значения $1и $2до конца файла.

Лично я бы использовал вторую команду с printf, так как вы можете просто использовать один набор кавычек вместо того, чтобы заключать в кавычки totalи запятую. Кроме того, он более модульный, как вы обнаружите, прочитав его справочную страницу. Я включаю только две команды, чтобы показать два разных способа.

Выход

title
total AAA,111
total BBB,222
total CCC,333
end
4
28.01.2020, 02:14

Хотя ваша конкретная проблема гораздо лучше решается с помощью утилиты обработки текста , такой как awk, как показано @Nasir (, см. также Почему использование цикла оболочки для обработки текста считается плохой практикой? ), отвечу на вопрос в заголовке.

Синтаксис for i j in words...; do something with $i and $j; doneсоответствует синтаксису zsh, еще не поддерживаемому bash.

Также bashвыполняет как разбиение (, которое вам нужно ), так и подстановку (, которую вы не хотите )после`cmd`(устаревшей формы подстановки команд, вы можете переключиться на $(cmd)), а zshвыполняет расщепление только так, как вы ожидаете.

Для обработки двух слов за раз с помощью bashили других POSIX-подобных -оболочек вместо for i j in words...вы можете выполнить:

set -- words...
while [ "$#" -gt 0 ]; do
  i=$1 j=$2 # or j=${2-missing}
  something with "$i" and "$j"
  shift "$(( 2 - ($# == 1) ))"
done

В вашем случае setбудет выглядеть как:

set -o noglob # disable globbing
set -- $(cat list)

(предполагает немодифицированный $IFS, который по умолчанию содержит пробел, табуляцию и новую строку ).

1
28.01.2020, 02:14

Теги

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