В оболочке Linux, как я могу обрабатывать каждую строку многострочной строки?

В оболочке Linux у меня есть строка, которая имеет следующее содержимое:

cat
dog
bird

и я хочу передать каждый элемент в качестве аргумента другой функции. Как я могу это сделать?

Ответы

Ответ 1

Используйте это (это цикл чтения каждой строки из файла file)

cat file | while read -r a; do echo $a; done

где echo $a - это то, что вы хотите сделать с текущей строкой.

ОБНОВЛЕНИЕ: от комментаторов (спасибо!)

Если у вас нет файла с несколькими строками, но есть переменная с несколькими строками, используйте

echo "$variable" | while read -r a; do echo $a; done

UPDATE2: "read -r" рекомендуется отключить интерпретацию символов с обратной сглаженностью (\) (отметьте комментарии mtraceur, поддерживаемые в большинстве оболочек). Это описано в POSIX 1003.1-2008 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html

По умолчанию, если не указана опция -r, <backslash> будет действовать как escape-символ... Поддерживается следующий параметр: -r - Не обрабатывать символ <backslash> особым образом. Рассмотрим каждую из них как часть входной строки.

Ответ 2

Просто передайте строку своей функции:

function my_function
{
    while test $# -gt 0
    do
        echo "do something with $1"
        shift
    done
}
my_string="cat
dog
bird"
my_function $my_string

дает вам:

do something with cat
do something with dog
do something with bird

И если вы действительно заботитесь о том, чтобы другие пробелы принимались как разделители аргументов, сначала установите IFS:

IFS="
"
my_string="cat and kittens
dog
bird"
my_function $my_string

чтобы получить:

do something with cat and kittens
do something with dog
do something with bird

Не забывайте unset IFS после этого.

Ответ 3

если вы используете bash, настройка IFS - это все, что вам нужно:

$ x="black cat
brown dog
yellow bird"
$ IFS=$'\n'
$ for word in $x; do echo "$word"; done
black cat
brown dog
yellow bird

Ответ 4

Используйте read с циклом while:

while read line; do
    echo $line;
done

Ответ 5

Используйте xargs:

В зависимости от того, что вы хотите делать с каждой строкой, это может быть просто:

xargs -n1 func < file

или более сложным, используя:

cat file | xargs -n1 -I{} func {}