你如何为文件的每一行运行一个命令?
例如,现在我正在使用以下命令来更改一些文件的Unixpath,这些文件是我写入文件的:
cat file.txt | while read in; do chmod 755 "$in"; done
有没有更优雅,更安全的方法?
如果你的文件不是太大,并且所有的文件都命名得很好 (没有空格或其他特殊的字符如引号),你可以简单地:
chmod 755 $(<file.txt)
如果你在file.txt
有特殊的字符和/或很多行。
xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)
如果您的命令需要通过input正好运行一次:
xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)
这个例子不需要,因为chmod
接受多个文件作为参数,但是这个匹配问题的标题。
对于某些特殊情况,甚至可以在由xargs
生成的命令中定义文件参数的位置:
xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)
是。
while read in; do chmod 755 "$in"; done < file.txt
这样你可以避免一个cat
过程。
cat
对于这样的目的几乎总是不好的。 你可以阅读更多关于无用的猫。
如果你有一个不错的select器(例如dir中的所有.txt文件),你可以这样做:
for i in *.txt; do chmod 755 "$i"; done
bash for循环
或您的一个变种:
while read line; do chmod 755 "$line"; done <file.txt
如果你知道input中没有空格:
xargs chmod 755 < file.txt
如果path中可能有空白,并且您有GNU xargs:
tr '\n' '\0' < file.txt | xargs -0 chmod 755
如果你想为每一行并行运行你的命令,你可以使用GNU并行
parallel -a <your file> <program>
文件的每一行都会作为parameter passing给程序。 默认情况下, parallel
运行多个线程作为您的CPU数量。 但是你可以用-j
指定它
我看到你标记bash,但Perl也是一个很好的方法来做到这一点:
perl -p -e '`chmod 755 $_`' file.txt
你也可以申请一个正则expression式,以确保你得到正确的文件,例如只处理.txt文件:
perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt
要“预览”发生了什么事情,只需用双引号replace反引号并预先print
:
perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt