我有一个文本文件 ( file.txt
),其中记录了所有需要执行命令的文件的路径。如何迭代循环for
并在文本文件的每个路径上对文件执行命令?我尝试过以下方法:
#!/bin/sh
LOC=pathto the file
for f in $LOC;
do
sed -i '1i\10004' $f;
done
答案1
你不需要 shell 循环,因为即使如此-i
,该sed
命令也接受多个文件名参数并分别对每个命名文件进行操作。除非所有文件都已完全备份,否则我鼓励您使用-- 和您喜欢的任何后缀,不必是。在不制作备份文件的情况下使用通常会导致意外的数据丢失。(如果您在循环中为每个文件运行一次,此建议同样适用。)-i.bak
.bak
sed -i
sed
由于sed
接受多个文件名参数,并且您可以使用xargs
而不是使用循环来构建文件名列表并将它们传递给sed
,您可以在一个简短的命令中完成所有操作。根据您的需要,您可以只运行该命令,而不必编写脚本。或者您的脚本可能只包含该命令,除了#!/bin/sh
顶部的 hashbang。您不需要使用任何 shell 变量,也不需要使用任何循环或 shell 中的其他控制结构。(使用 shell 脚本中的循环处理文本(例如文件名列表)是通常不是最好的方法。
我假设输入文件每行包含一个文件名,尽管用空字符而不是换行符分隔文件名会更好(因为即使某些文件名包含换行符,它也能正常工作)。假设是这种情况,您可以使用以下命令:
xargs -d'\n' -a files sed -i.bak '1i\10004'
-d'\n'
告诉xargs
它读取的文件名由换行符分隔,也就是说,它们在输入文件中每行出现一个。-a files
告诉xargs
从名为的文件中读取其输入files
. (您可以使用重定向并改写,就像通常做的那样。)替换<files
-a files
files
使用您想要读取文件名的文件的实际文件名。-i.bak
执行就地修改( ),如您所知。在同一个命令行参数中-i
包含没有空格的,表示使用.bak
sed
.bak
后缀。如果您想要不同的后缀,请使用该后缀,而不是.bak
。 如果你真的想要执行此操作而不创建备份文件,那么您可以简单地省略后缀并只写-i
。- 如您所知,
'1i\10004'
传递1i\10004
给sed
use 作为处理文件行的命令。(其他读者可能希望用sed
他们正在使用的任何命令替换它。)