如何为文件的每一行运行命令?

时间:2021-01-13 19:40:49

For example, right now I'm using the following to change a couple of files whose Unix paths I wrote to a file:

例如,现在我正在使用以下内容来更改我写入文件的Unix路径的几个文件:

cat file.txt | while read in; do chmod 755 "$in"; done

Is there a more elegant, safer way?

有更优雅,更安全的方式吗?

7 个解决方案

#1


71  

If your file is not too big and all files are well named (without spaces or other special chars like quotes), you could simply:

如果您的文件不是太大而且所有文件都命名良好(没有空格或其他特殊字符,如引号),您可以简单地:

chmod 755 $(<file.txt)

If you have special chars and/or a lot of lines in file.txt.

如果你在file.txt中有特殊的字符和/或很多行。

xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)

if your command need to be run exactly 1 time by entry:

如果您的命令需要通过条目正好运行一次:

xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)

This is not needed for this sample, as chmod accept multiple files as argument, but this match the title of question.

这个示例不需要这样,因为chmod接受多个文件作为参数,但这与问题的标题相匹配。

For some special case, you could even define location of file argument in commands generateds by xargs:

对于某些特殊情况,您甚至可以在xargs生成的命令中定义文件参数的位置:

xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)

#2


104  

Yes.

是。

while read in; do chmod 755 "$in"; done < file.txt

This way you can avoid a cat process.

这样你就可以避免cat进程。

cat is almost always bad for a purpose such as this. You can read more about Useless Use of Cat.

对于像这样的目的,猫几乎总是不好的。您可以阅读有关Catless Use of Cat的更多信息。

#3


11  

If you know you don't have any whitespace in the input:

如果您知道输入中没有任何空格:

xargs chmod 755 < file.txt

If there might be whitespace in the paths, and if you have GNU xargs:

如果路径中可能有空格,并且您有GNU xargs:

tr '\n' '\0' < file.txt | xargs -0 chmod 755

#4


10  

if you have a nice selector (for example all .txt files in a dir) you could do:

如果你有一个漂亮的选择器(例如dir中的所有.txt文件)你可以这样做:

for i in *.txt; do chmod 755 "$i"; done

bash for loop

bash for loop

or a variant of yours:

或者你的变种:

while read line; do chmod 755 "$line"; done <file.txt

#5


8  

If you want to run your command in parallel for each line you can use GNU Parallel

如果要为每一行并行运行命令,可以使用GNU Parallel

parallel -a <your file> <program>

Each line of your file will be passed to program as an argument. By default parallel runs as many threads as your CPUs count. But you can specify it with -j

文件的每一行都将作为参数传递给程序。默认情况下,并行运行与CPU计数一样多的线程。但是你可以用-j指定它

#6


2  

I see that you tagged bash, but Perl would also be a good way to do this:

我看到你标记了bash,但Perl也是一个很好的方法:

perl -p -e '`chmod 755 $_`' file.txt

You could also apply a regex to make sure you're getting the right files, e.g. to only process .txt files:

您还可以应用正则表达式以确保获得正确的文件,例如只处理.txt文件:

perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt

To "preview" what's happening, just replace the backticks with double quotes and prepend print:

要“预览”正在发生的事情,只需用双引号替换反引号并添加前缀:

perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt

#7


0  

You can also use AWK which can give you more flexibility to handle the file

您还可以使用AWK,它可以让您更灵活地处理文件

awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt

if your file has a field separator like:

如果您的文件有一个字段分隔符,如:

field1,field2,field3

字段1,字段2,字段3

To get only the first field you do

只获得第一个字段

awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt

You can check more details on GNU Documentation https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple

您可以查看有关GNU文档的更多详细信息https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple

#1


71  

If your file is not too big and all files are well named (without spaces or other special chars like quotes), you could simply:

如果您的文件不是太大而且所有文件都命名良好(没有空格或其他特殊字符,如引号),您可以简单地:

chmod 755 $(<file.txt)

If you have special chars and/or a lot of lines in file.txt.

如果你在file.txt中有特殊的字符和/或很多行。

xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)

if your command need to be run exactly 1 time by entry:

如果您的命令需要通过条目正好运行一次:

xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)

This is not needed for this sample, as chmod accept multiple files as argument, but this match the title of question.

这个示例不需要这样,因为chmod接受多个文件作为参数,但这与问题的标题相匹配。

For some special case, you could even define location of file argument in commands generateds by xargs:

对于某些特殊情况,您甚至可以在xargs生成的命令中定义文件参数的位置:

xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)

#2


104  

Yes.

是。

while read in; do chmod 755 "$in"; done < file.txt

This way you can avoid a cat process.

这样你就可以避免cat进程。

cat is almost always bad for a purpose such as this. You can read more about Useless Use of Cat.

对于像这样的目的,猫几乎总是不好的。您可以阅读有关Catless Use of Cat的更多信息。

#3


11  

If you know you don't have any whitespace in the input:

如果您知道输入中没有任何空格:

xargs chmod 755 < file.txt

If there might be whitespace in the paths, and if you have GNU xargs:

如果路径中可能有空格,并且您有GNU xargs:

tr '\n' '\0' < file.txt | xargs -0 chmod 755

#4


10  

if you have a nice selector (for example all .txt files in a dir) you could do:

如果你有一个漂亮的选择器(例如dir中的所有.txt文件)你可以这样做:

for i in *.txt; do chmod 755 "$i"; done

bash for loop

bash for loop

or a variant of yours:

或者你的变种:

while read line; do chmod 755 "$line"; done <file.txt

#5


8  

If you want to run your command in parallel for each line you can use GNU Parallel

如果要为每一行并行运行命令,可以使用GNU Parallel

parallel -a <your file> <program>

Each line of your file will be passed to program as an argument. By default parallel runs as many threads as your CPUs count. But you can specify it with -j

文件的每一行都将作为参数传递给程序。默认情况下,并行运行与CPU计数一样多的线程。但是你可以用-j指定它

#6


2  

I see that you tagged bash, but Perl would also be a good way to do this:

我看到你标记了bash,但Perl也是一个很好的方法:

perl -p -e '`chmod 755 $_`' file.txt

You could also apply a regex to make sure you're getting the right files, e.g. to only process .txt files:

您还可以应用正则表达式以确保获得正确的文件,例如只处理.txt文件:

perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt

To "preview" what's happening, just replace the backticks with double quotes and prepend print:

要“预览”正在发生的事情,只需用双引号替换反引号并添加前缀:

perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt

#7


0  

You can also use AWK which can give you more flexibility to handle the file

您还可以使用AWK,它可以让您更灵活地处理文件

awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt

if your file has a field separator like:

如果您的文件有一个字段分隔符,如:

field1,field2,field3

字段1,字段2,字段3

To get only the first field you do

只获得第一个字段

awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt

You can check more details on GNU Documentation https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple

您可以查看有关GNU文档的更多详细信息https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple