Macos 如何在Mac OSX上使用Zsh shell和'sed'命令重命名文件

Macos 如何在Mac OSX上使用Zsh shell和'sed'命令重命名文件,macos,shell,sed,zsh,Macos,Shell,Sed,Zsh,我的桌面上有一个名为“图像”的文件夹,里面有3个图像 File-A-B.gif File-C-D.gif File-E-F.gif …我想重命名命令行上的文件,以便删除第二个连字符/破折号。因此,结果将是命名为这样的文件 File-AB.gif File-CD.gif File-EF.gif …我使用的是通过管道互相传递的命令组合,但在让它们工作方面运气不佳 最初我有ls文件-*|sed's/\(文件-[^-]\)-\(.+\)/mv&\1\2/'| sh 此命令的故障是 列出所有以Fil

我的桌面上有一个名为“图像”的文件夹,里面有3个图像

File-A-B.gif
File-C-D.gif
File-E-F.gif
…我想重命名命令行上的文件,以便删除第二个连字符/破折号。因此,结果将是命名为这样的文件

File-AB.gif
File-CD.gif
File-EF.gif
…我使用的是通过管道互相传递的命令组合,但在让它们工作方面运气不佳

最初我有
ls文件-*|sed's/\(文件-[^-]\)-\(.+\)/mv&\1\2/'| sh

此命令的故障是

  • 列出所有以
    File-
  • 通过管道将结果传送到
    sed
  • 我们将使用
    sed
    捕获名称的不同部分
  • 查看第一个文件,我们将捕获
    文件-A
    B.gif
  • 然后,使用
    sed
    用move命令替换匹配的文件名,并有效地告诉它将原始文件重命名为由我们捕获的两段数据组成的文件
  • 然后,我们通过管道将该命令传递到
    sh
我得到的最初错误是权限错误。我不知道为什么,因为我对这些文件有“读写”权限

要解决此问题,请输入I
chmod 777
每个文件

这就导致了一个新的错误,
无法执行二进制文件

为了解决这个错误,我看到了这篇文章:它建议添加一对额外的单引号。这种方法之所以有效(显然),是因为
sed
会出错,因为它不知道要使用什么文件扩展名,但放置一个空字符串可以消除该错误(旁注:我的理解是,您还需要使用
-i
标志-我没有使用-但这样做会导致不同的错误,所以我放弃了这一点,只使用了单引号以避免出现二进制文件错误)

现在我有了
ls文件-*|sed''s/\(文件-[^-]\)-\(.+\)/mv&\1\2/''sh

但是这个错误与
没有这样的文件或目录

我试图明确文件的位置,例如

ls File-* | sed '' 's/\(File-[^-]\)-\(.+\)/mv ~\/Desktop\/Images\/& ~/Desktop\/Images\/\1\2/' | sh
…注意,我不得不避开前斜杠
~\/Desktop\/Images\/
,但这仍然不起作用

我还使用自制软件安装了GNU版的
sed
,但它也出现了与
gsed类似的错误:无法读取s/\(Vim-[^-]\)-\(.+\)/mv&\1\2/:没有这样的文件或目录

我有点不知所措,不知道如何才能让它发挥作用

我不想求助于编写bash/zsh脚本或Ruby脚本


如果您能给我任何帮助,我将不胜感激。

以下内容对您来说应该很有用:

ls File-* | sed 's/\(.*\)-\(.*\)/mv & \1\2/' | sh
你试过什么

ls File-* | sed '' 's/\(File-[^-]\)-\(.+\)/mv & \1\2/' | sh
非常接近,说:

ls File-* | sed '' 's/\(File-[^-]*\)-\(.*\)/mv & \1\2/' | sh

如果您使用的是
zsh
,您不需要使用
sed
:有一个非常简单的方法可以实现这一点:

$ ls -F -G
File-A-B.gif  File-C-D.gif  File-E-F.gif

$ zmv -n 'File-(*)-(*).gif' 'File-${1}${2}.gif'
mv -- File-A-B.gif File-AB.gif
mv -- File-C-D.gif File-CD.gif
mv -- File-E-F.gif File-EF.gif
注意:省略
-n
以使其实际运行

它通过匹配括号内的内容来工作.gif将同时匹配
File-A-B.gif
,并保存
A
B
,以便我们以后可以引用它们。然后,我们将刚刚匹配的文件移动到一个新文件名,省略两个字母之间的连字符,并使用引用插入字母:
File-${1}${2}.gif


这是一个非常强大的小模块,只要你能给它两个正则表达式:一个匹配要重命名的文件,第二个匹配重命名的文件名。

谢谢!你提到的第一个选项似乎对我有用,但它确实在输出中产生了错误(即使它正确地重命名了文件)?错误是
preexec:4:command not found:^A^B
你知道这意味着什么吗?旁注,你说的上一个示例几乎就是我的示例,但不起作用。但是我可以理解为什么第一个版本可以工作(我想),我们使用
echo
$()
。不过,我不能100%确定
$()
通常用于什么?您能否在您的回答中添加额外的解释,以帮助我(和其他人)更好地理解:)
$()
是流程替代。我想,既然我们反正是管道到
sh
那就不需要了。请参见上面的编辑。这很有意义。谢谢让其他阅读本文的人明白一点:我在最初的版本中犯了两个错误。最大的错误是我使用了
+
(regexp中的典型意思是“一个或多个”),但这不受支持,所以我需要
*
(意思是“零或多个”)。另一个没有影响任何事情但可能会引起其他人困惑的错误是我错过了一个
*
。所以
(File-[^-]\)
通过了
File-A-B.gif
,但是会失败
File-AB-C.gif
,所以它应该是
(File-[^-]*\)
(即
[^-]*
意味着“匹配任何不是
-
的东西零次或多次”)。顺便说一句,我很想看看它是如何使用
$()
但是
ls File-*|sed's/\(.*\)-\(.*\)/echo$(mv&\1\2)/'
为我生成了一个错误,所以我猜
echo$()
部分本身不工作?如果
zsh:未找到命令:zmv
自动加载-U zmv
加载它。有关此函数的详细信息
zsman-hcontrib