如何对多个文件执行字符串替换?

How to execute a string substitution on multiple files?

我在某个位置 (/subdirectory1) 有几十个 bash 脚本,文件中的路径名 (pathname1) 不正确。对于该子目录中的所有 bash 脚本 *.sh,我想以某种方式将此路径名替换为 pathname2

有没有标准的方法来做到这一点?

在 perl 中,如果我正在处理单个文件 file1,我将执行:

perl -pi -e 's/pathname1/pathname2/g' file1

如何对所有文件完成此操作,*.sh

它不一定是在 perl 中,但这是我想到的一种方式。我怀疑还有一种方法可以用其他 shell 脚本和其他语言来做到这一点---我会很乐意编辑这个问题以缩小选项范围。

您可以先 运行 find 列出文件,然后 运行 perlsed 或其他文件:

find . -name '*.sh' -exec <perl_command> {} \;

注意 {} \;,这意味着 运行 每个 find 输出。

只需使用文件 glob:

perl -pi -e 's@pathname1@pathname2@g' *.sh

这将很好地处理包含空格的病态文件名。

只列出所有的文件名,都是逐行处理的

perl -pi -e 's{pathname1}{pathname2}g' *.sh

其中 {} 用于分隔符,因此路径中的 / 无需转义。

这假定 *.sh 指定了您需要的文件。


我们可以看到是这样 运行

perl -MO=Deparse -ne '' file1 file2

输出

LINE: while (defined($_ = <ARGV>)) {
    '???';
}
-e syntax OK

这是相当于单行代码的代码,由 -MO=Deparse 提供。它向我们展示了循环是根据 <ARGV> 提供的输入设置的。

那么这里的 <ARGV> 是什么?来自 I/O Operators in perlop

The null filehandle <> is special: ... Input from <> comes either from standard input, or from each file listed on the command line.

哪里

<> is just a synonym for <ARGV>

所以输入将是所有提交文件的所有行。