查找文本为"example.html"的所有文件,并替换为"example.php",仅当文件名中没有空格时才有效

Tia*_*ago 5 unix bash grep sed xargs

我已经使用以下方法在文件中进行递归查找和替换,以更新hrefs以正确指向新页面:

#!/bin/bash
oldstring='features.html'
newstring='features.php'
grep -rl $oldstring public_html/ | xargs sed -i s@"$oldstring"@"$newstring"@g
Run Code Online (Sandbox Code Playgroud)

它起作用了,除了一些名称中有空格的文件.

这不是问题,因为名称中包含空格的文件是我在测试新内容时创建的备份/重复项.但是我想了解如何在此查询中将带空格的路径正确传递给sed命令.有人知道如何在这个"单线"中纠正这个问题吗?

Sto*_*ica 1

这是一个懒惰的方法:

grep -rl $oldstring public_html/ | xargs -d'\n' sed -i "s@$oldstring@$newstring@g"
Run Code Online (Sandbox Code Playgroud)

默认情况下,xargs使用空格作为来自输入的参数的分隔符。例如,如果您有两个文件a b和c,那么它将执行以下命令:

sed -i 's/.../.../' a b c
Run Code Online (Sandbox Code Playgroud)

通过xargs明确指示使用换行符作为分隔符,-d '\n'它将正确地处理a b为单个参数并在运行命令时引用它:

sed -i 's/.../.../' 'a b' c
Run Code Online (Sandbox Code Playgroud)

我称之为惰性方法,因为正如@Barmar指出的那样,如果您的文件名称中包含换行符,则这将不起作用。如果您需要处理此类情况,请使用 @Barmar 的方法和find ... -print0andxargs -0 ...

PS:我也改为了s@"$oldstring"@"$newstring"@g,"s@$oldstring@$newstring@g"这是等效的,但更具可读性。