Bash xargs:command substitution$(…)与pipe不匹配';行不通

Bash xargs:command substitution$(…)与pipe不匹配';行不通,bash,pipe,command-substitution,Bash,Pipe,Command Substitution,我正在尝试编写短脚本,并执行以下命令: echo "aaa111 bbb111" | xargs -I {} echo {} | sed 's/111/222/g' 返回我所期望的aaa222 bbb222 我期待下一个命令: echo "aaa111 bbb111" | xargs -I {} echo $(echo {} | sed 's/111/222/g') 返回相同的值,但它返回aaa111 bbb111!为什么呢 UPD:我正在努力实现的目标: 我有很多文件,比如pic30-c

我正在尝试编写短脚本,并执行以下命令:

echo "aaa111 bbb111" | xargs -I {} echo {} | sed 's/111/222/g'
返回我所期望的
aaa222 bbb222

我期待下一个命令:

echo "aaa111 bbb111" | xargs -I {} echo $(echo {} | sed 's/111/222/g')
返回相同的值,但它返回
aaa111 bbb111
!为什么呢


UPD:我正在努力实现的目标:

我有很多文件,比如
pic30-coff-gcc
pic30-coff-ag
,我需要为每个文件创建一个符号链接,比如
pic30-gcc
->
pic30-coff-gcc
,等等

所以我写了这个:

ls|grep 'coff-'|xargs -I {} ln -s {} $(echo {} | sed 's/coff-//g')
它不工作:对于每个文件,它报告该文件存在。我像这样检查命令:

ls|grep 'coff-'|xargs -I {} echo "ln -s {} $(echo {} | sed 's/coff-//g')"
是的,
sed
部分不工作:

ln -s pic30-coff-gcc pic30-coff-gcc
ln -s pic30-coff-gcc-4.0.3 pic30-coff-gcc-4.0.3
...
但是如果我只是打字

echo "ln -s pic30-coff-gcc $(echo pic30-coff-gcc | sed 's/coff-//g')"
它的工作原理是:

ln -s pic30-coff-gcc pic30-gcc
然后我用
aaa111
编写了测试命令,但它也不起作用。仍然无法理解原因。

$(echo{}sed's/111/222/g')
在作为参数传递给
xargs
之前进行评估。它将返回
{}

因此:

echo "aaa111 bbb111" | xargs -I {} echo $(echo {} | sed 's/111/222/g')

echo "aaa111 bbb111" | xargs -I {} echo {}

似乎您只需要一个简单的循环:

for file in *coff*; do
  ln -s "${file}" "${file/coff-/}"
done

for
循环答案正是我来这里读的。
xargs
的全部目的就是避免这种循环
xargs
对于这种特殊情况可能不是最聪明的工具,但问题在于它

这是我最终得到的解决方案。它可能并不完美,但仍然有效:

echo "aaa111 bbb111" | xargs -I {} sh -c "echo \$(echo {} | sed 's/111/222/g')"
# Outputs aaa222 bbb222
您可以使用同一命令的不同变体:

echo "aaa111 bbb111" | xargs -I {} sh -c 'echo $(echo {} | sed "s/111/222/g")'
echo "aaa111 bbb111" | xargs -I {} sh -c "echo \`echo {} | sed 's/111/222/g'\`"

这里的要点只是调用一个新的shell,在
xargs
用正确的内容替换
replace str
(这里
{}
)之后,它将执行命令替换,然后强制
xargs
一次读取两个参数

#旁白:避免使用ls | grep
printf“%s\n”coff-*|
sed's/\(coff-\(.*)\)/\1\2/'|
xargs-n2-ln-s

这显然是易碎的;如果文件名中包含空格,则会对其进行错误的分析。

更好的公式是
echo“aaa111 bbb111”| xargs-I@@bash-c'temp=“@”;echo${temp//111/222}'
虽然正确,但这里的目标是使用与OP相同的命令。