Отправить каждую строку как один аргумент в bash - PullRequest
0 голосов
/ 12 февраля 2012

У меня есть переменная в bash, которая похожа на

filenames='file 1
file 2
file 3'

Мне нужно отправить каждую строку в содержимом вышеупомянутой переменной в качестве одного аргумента в программу. Но я не могу разобраться с этим. Вот что я попробовал:

python -c 'import sys; print sys.argv' $filenames
['-c', 'file', '1', 'file', '2', 'file', '3']

или

python -c 'import sys; print sys.argv' "$filenames"
['-c', 'file 1\nfile 2\nfile 3']

Я ожидаю что-то вроде этого

['-c', 'file 1', 'file 2', 'file 3']

Я тоже пытался поиграть с настройкой IFS, но не смог сделать это правильно. Есть идеи по этому поводу?

Ответы [ 5 ]

2 голосов
/ 12 февраля 2012
$ export filenames="file 1
file 2
file 3"
$ echo "$filenames" | xargs -d\\n python -c 'import sys; print sys.argv'
['-c', 'file 1', 'file 2', 'file 3']

Другой способ использования read вместо xargs:

#!/bin/bash
filenames="file 1
file 2
file 3"
cmd="python -c 'import sys; print sys.argv; print sys.stdin.readlines()'"
while read file
do
    args="$args \"$file\""
done < <(echo "$filenames")
echo $cmd $args
echo `echo hi | sh -c "$cmd $args"`

Выход:

$ ./test.sh 
python -c 'import sys; print sys.argv; print sys.stdin.readlines()' "file 1" "file 2" "file 3"
['-c', 'file 1', 'file 2', 'file 3'] ['hi\n']
1 голос
/ 12 февраля 2012

Двойная оценка команды с помощью eval или sh -c может привести к странным ошибкам, если вы не получите правильный уровень цитирования.Вместо этого я бы рекомендовал использовать массив, либо просто сохранив список файлов в виде массива для начала:

filearray=("file 1" "file 2" "file 3")
python -c 'import sys; print sys.argv' "${filearray[@]}"

, либо преобразовав его из строки с разделителями новой строки в массив:

filenames='file 1
file 2
file 3'
oldIFS="$IFS"; IFS=$'\n'
filearray=($filenames)
IFS="$oldIFS"
python -c 'import sys; print sys.argv' "${filearray[@]}"
1 голос
/ 12 февраля 2012

Просто чтобы добавить другую опцию,

OLDIFS=$IFS
IFS='
'
set -- $filenames
python -c 'import sys; print sys.argv; print sys.stdin.readlines()' "$@"
IFS=$OLDIFS

Редактировать: Добавить код, чтобы сохранить старое значение в OLDIFS и восстановить его впоследствии.IFS='whatever' set -- $var на одной строке не работает.

0 голосов
/ 19 июня 2014

А как же Xargs:

$ seq 10 | xargs  python -c 'print __import__("sys").argv'
['-c', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
0 голосов
/ 12 февраля 2012

Еще один вариант:

while read line ; do
  python -c 'import sys; print sys.argv' $line;
done <(echo $filenames)
...