我有一个文件列表,我想在其中检查某个特定字符串。如果文件中存在该字符串,我想用我拥有的新版本替换它。最简单的方法是什么?
答案1
for file in "`grep -l "foo" bar gazi`"; do cp -p --backup=numbered replace "$file"; done
在哪里代替是替换文件的路径,酒吧和加齐表示要检查的文件列表,以及富是感兴趣的搜索字符串。
如果您需要额外的帮助来为 grep (上文) 制定适当的正则表达式,请随时询问。
答案2
grep 可以在文件中搜索字符串,如果找到则返回 0,您可以将其用作条件的一部分来替换文件,例如:
#!/bin/bash
if [ !`/bin/grep -q teststring /path/to/file` ]; then
cp newfile oldfile
fi
答案3
假设您有一个包含文件列表的文件?我不知道您是否有一个要替换匹配文件的静态文件,或者每个文件都有潜在的替换文件。这处理了第二种情况,对于第一种情况,只需将 $i.new 替换为静态文件名即可。
for i in `cat /var/tmp/listoffiles` ; do
if grep string $i > /dev/null 2>&1 ; then
cp $i $i.old
cp $i.new $i
fi
done
答案4
在 shell 脚本中循环处理文件的正确方法是将命令导入while
或将文件重定向到循环done
语句中while
。这将处理除包含换行符之外的任何名称。您不应使用以下形式for f in $(cmd)
。
在此示例中,find
是生成文件列表的命令:
find . -type f -name "*.txt" | while read -r filename
do
if grep -qs "$string" "$filename" # or use >/dev/null 2>&1 instead of -qs
then
cp "$replacement" "$filename"
fi
done
或者,此处的列表包含在一个文件中:
while read -r filename
...
done < "$file_with_list"
另一种方法是使用xargs
。
对于生成文件列表的命令(例如find
):
find . -type f -name "*.txt" -print0 | xargs -0 -I % env string=$string sh 'grep -qs "$string" "%" && cp replacement_file "%"'
当文件名可能包含换行符时,上述方法将起作用。
如果列表在文件中:
xargs -a "$file_with_list" -I % env string=$string sh 'grep -qs "$string" "%" && cp replacement "%"'
当文件名可能包含空格时,所有这些示例都将起作用。