我有一个执行以下操作的shell脚本:
INPUT_DIR是一个包含zip文件的目录。 zip文件看起来像lograw1.zip,lograw2.zip等。
我有一个名为prog.py的程序,它使用选项-i将输入作为zip文件输出并输出tsv文件。与每个zip文件对应的tsv文件具有不同的名称。
即,lograw1.zip给出了logproces1.tsv
的输出我有一个带有for for循环的shell脚本,它运行正常。
for f in $INPUT_DIR/*.zip
do
filename=$(basename $f .zip)
tsvfilename="$(basename "${f/raw/processed}" .zip).tsv"
python /work/prog.py -i $f $OUTPUT_DIR/$tsvfilename
done
我想在bash脚本中使用xargs来读取拉链并提交给我的prog进行类似的文件重命名。如何使用xargs作为命令之间的参数发送? 提前谢谢。
答案 0 :(得分:4)
xargs的工作方式是从标准输入中获取文件名列表,并运行一个命令,其中包含从标准输入中检索的所有文件。如果标准输入的长度将溢出命令行缓冲区,xargs
将分割列表。
让我们做一些简单的事情:
ls | xargs /bin/echo
假设您的目录如下所示:
ls
命令将输出:
foo bar barfoo foobar barbar foofoo
这将传递给/bin/echo
,并执行以下操作:
/bin/echo foo bar barfoo foobar barbar foofoo
现在,假设您的输入缓冲区只有12个字符长,将所有这些文件传递给/bin/echo
将超出输入缓冲区。 xargs
将确保它不会将超过10个字符的数据传递给/bin/echo
命令,并将一遍又一遍地重新执行/bin/echo
命令直到所有文件传递给它:
/bin/echo foo bar
/bin/echo barfoo foobar
/bin/echo barber foofoo
您可以将-s10
参数传递给xargs
,以限制xargs
将占用的字符数,从而对此进行测试。您还可以尝试-t
,它将完全回显xargs
正在执行的内容。
本教程的原因是要了解为了使xargs
能够正常工作,shell脚本的每个命令都必须能够使用多个文件,而实际情况并非如此。 /work/prog.py
看起来一次只需要一个文件,basename
命令也是如此。
您必须修改脚本才能利用xargs
才能使其正常运行。可能通过使用for
循环来处理这个问题。
考虑将find
与您的shell脚本一起使用,它可以做您想做的事情:
find . -name "*.zip" -exec script.sh {} \;
xargs
存在问题(默认情况下它不会处理带有时髦字符的文件名),并且有一个问题是它是否更快。毕竟:
rm *
仍然必须一次删除传递给它的文件,就像这个小脚本一样:
for file in *
do
rm $file
done
在旧的Unix时代,开始一个新进程需要花费很多开销,所以如果你可以运行一次命令而不是多次运行,它可以节省你的时间。我不知道现在是否值得这么麻烦。