xargs 命令中的字符串替换失败

xargs 命令中的字符串替换失败

我正在尝试自动创建目录的符号链接,并在链接名称 (bar) 中替换原始名称的某个文本字符串 (foo)。目标目录的名称可能包含空格(例如“foo with whitespace”)。

这是一个最小的例子:

> ls -Q

"foo"
"foo with whitespace"

我正在尝试以下命令(使用 xargs 的 -p 选项在执行之前调试/检查结果):

find . -iname "*foo*" -print0 | xargs -0 -I '{}' -p ln -s {} `echo {} | sed -e s#foo#bar#g

我想要的结果是这样的:

ln -s 'foo with whitespace' 'bar with whitespace'
ln -s 'foo' 'bar'

但是字符串替换失败。实际输出如下所示:

ln -s './foo with whitespace' './foo with whitespace'?...
ln -s ./foo ./foo?...

如果我使用常量字符串而不是 {},则字符串替换将按预期工作:

find . -iname "*foo*" -print0 | xargs -0 -I '{}' -p ln -s {} `echo "foo" | sed -e s#foo#bar#g`

ln -s './foo with whitespace' bar?...
ln -s ./foo bar?...

我的错误是什么以及如何修复命令调用?

编辑:Tilman Schmidt 的解决方案奇迹般有效。

答案1

命令替换

`echo {} | sed -e s#foo#bar#g`

仅执行一次,运行由find和命令组成的管道。因此获取字符串作为输入,并且未找到,则将其原封不动地输出。 xargssed{}foo然后shell 运行结果命令行

find . -iname "*foo*" -print0 | xargs -0 -I '{}' -p ln -s {} {}

因此,命令替换在这里不是合适的工具。尝试以下方法

find . -iname "*foo*" -print | while read f; do ln -s "$f" "${f//foo/bar}"; done

(未经测试)代替。请注意,如果您的文件名包含换行符,则此方法无效。

相关内容