在bash中将每一行作为单个参数发送

时间:2012-02-12 10:02:09

标签: bash shell command-line-arguments

我在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 个答案:

答案 0 :(得分:2)

$ 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 :(得分:1)

只是添加另一个选项,

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

修改:添加代码以保存OLDIFS中的旧值并在之后恢复。单行上的IFS='whatever' set -- $var不起作用。

答案 2 :(得分:1)

使用evalsh -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[@]}"

答案 3 :(得分:0)

又一个选择:

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

答案 4 :(得分:0)

xargs怎么样:

$ seq 10 | xargs  python -c 'print __import__("sys").argv'
['-c', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']