为什么这个 xargs 命令不起作用?

为什么这个 xargs 命令不起作用?

我想删除所有 .sh 扩展名,所以这样做了:

ls *.sh | xargs -I {} mv {} `basename {} .sh`

但是它不起作用,它的行为就像basename返回未更改的文件名。

为什么会这样?

例如,这有效:

ls *.sh | xargs -I {} echo `basename {}.jpg .jpg`;

编辑:

解决方案:单引号可防止`basename ...`shell 在命令运行之前进行求值。

ls *.sh | xargs -I {}  sh -c 'mv {} `basename {} .sh`'

答案1

因为basename命令是在管道运行之前运行的。要完成这项工作,您需要 xargs 来执行 basename,您可以使用 来执行此操作sh -c,例如:

ls *.sh | xargs -L1 sh -c 'basename $1 .sh' dummy

笔记:

  • 如果您不知道xargs在哪里插入文件名,它们将被添加到命令行末尾。
  • 您应该使用-L1开关或其等效项,因此xargs仅将一个参数传递给sh.
  • 使用 的输出ls可能有不良影响

编辑

删除了已弃用的选项,感谢 TechZilla

答案2

我不确定你的问题,你真的在​​问为什么你的第一行不起作用吗?或者您正在寻找一种正确的方法来重命名所有 .sh 文件?

假设这是最干净的方法,我更喜欢在之前准备命令选项xargs。为了删除 .sh 文件扩展名,我经常考虑这种方法,

 find -maxdepth 1 -type f -iname '*.sh'  | sed 'p;s_.sh$__' | xargs -L2 mv

相关内容