如果文件包含特定字符串,则 Bash 脚本将替换该文件

如果文件包含特定字符串,则 Bash 脚本将替换该文件

我有一个文件列表,我想在其中检查某个特定字符串。如果文件中存在该字符串,我想用我拥有的新版本替换它。最简单的方法是什么?

答案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 "%"'

当文件名可能包含空格时,所有这些示例都将起作用。

相关内容