单个sed命令进行多个替换?

5

我使用sed在文件中替换文本。

我想要给sed一个包含所有需要在特定文件中搜索和替换的字符串的文件。

它可以应用于.h和.cpp文件。对于每个文件,它会搜索其中包含的文件名。如果找到了文件名,例如"a.h",则会将其替换为"<a.h>"(不带引号)。

这是脚本:

For /F %%y in (all.txt) do 
   for /F %%x in (allFilesWithH.txt) do
       sed -i s/\"%%x\"/"\<"%%x"\>"/ %%y
  • all.txt - 需要进行替换的文件列表
  • allFilesWithH.txt - 所有需要搜索的包含文件名

我不想多次运行sed命令(如在input.txt中的文件名数量),但我想运行单个sed命令并将其作为输入传递给input.txt。

我该怎么做呢?

P.S 我从VxWorks开发shell中运行sed,因此它没有Linux版本所具备的所有命令。


这个脚本是一个Windows BAT脚本吗?或者是VxWorks开发shell里的东西? - Peter Mortensen
是的,这是一个批处理文件(BAT)。 - Asaf
3个回答

8

您可以消除其中一个循环,这样sed每个文件只需要调用一次。使用-f选项指定多个替换:

For /F %%y in (all.txt) do 
    sed -i -f allFilesWithHAsSedScript.sed %%y

allFilesWithHAsSedScript.sed 是从 allFilesWithH.txt 派生而来的,它包含以下内容:

s/\"file1\"/"\<"file1"\>"/
s/\"file2\"/"\<"file2"\>"/
s/\"file3\"/"\<"file3"\>"/
s/\"file4\"/"\<"file4"\>"/

在文章《常见主题:Sed实例,第三部分》中,有许多带有解释的sed脚本示例。

不要被搞混了(双关语)。


链接已于2023年11月8日失效,但我认为相同的文章可以在https://www.latexstudio.net/shredderyin/src/sed/l-sed3.html找到。 - undefined

4

sed本身没有从文件中读取文件名的能力。我不熟悉VxWorks shell,我想这可能与缺乏答案有关...所以以下是一些在bash中有效的方法 - 也许VxWorks将支持其中之一。

sed -i 's/.../...' `cat all.txt`

sed -i 's/.../...' $(cat all.txt)

cat all.txt | xargs sed -i 's/.../...'

实际上,如果能完成任务,多次调用sed并不是什么大问题:

cat all.txt | while read file; do sed -i 's/.../.../' $file; done

for file in $(cat all.txt); do   # or `cat all.txt`
    sed -i 's/.../.../' $file
done

谢谢,我会尝试的。 这是一个大问题,因为它需要太多的时间和内存才能完成。这就是为什么我寻找另一种方法。 我希望它能有所帮助。谢谢。 - Asaf
多次运行sed不会比运行一次使用更多的内存。它需要更多的时间来运行,因为在生成新进程时有一些额外开销,我想每次构建正则表达式也有开销。如果你迫切想要避免这种开销,那么使用Perl而不是sed可能会更快。 - Tim
同意。多个连续调用不会增加内存使用量,特别是像sed这样逐行工作的程序。当然,时间会受到影响。当然,如果你有足够多的小文件(如果它们很大,替换大部分时间),那么你可能会进入太长的命令行领域。无论如何,这就是我提供前几种方法的原因。我猜shell没有命令替换功能,是吗? - Cascabel
实际上,现在采用建议的方式运行速度快多了。问题是PF使用量超过了2GB,然后我就无法运行更多的sed命令。 - Asaf

0
我会将所有的allFilesWithH.txt文件改成一个sed命令,使用sed来实现。(如果必须使用sed的话。实际上我会使用Perl代替,因为它也可以搜索*.h文件。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接