Bash 如何重命名使用find命令找到的文件

Bash 如何重命名使用find命令找到的文件,bash,find,renaming,Bash,Find,Renaming,我有一系列的音乐文件夹。有些文件名包含一个下划线,我想去掉它 与 我找到所有带下划线的文件。 似乎我可以将-execdir mv{}添加到命令中,但不知道从那里添加什么。 我认为{}将完整路径和文件名作为带有下划线的文件字符串提供,但我不知道如何使用类似sed's/\ug'的内容删除新文件名上的u。 任何帮助都将不胜感激。请尝试: find /Users/Chris/CDs -type f -name "*_*" -execdir bash -c 'mv -i -- "$1" "${1//_/}

我有一系列的音乐文件夹。有些文件名包含一个下划线,我想去掉它

我找到所有带下划线的文件。 似乎我可以将
-execdir mv{}
添加到命令中,但不知道从那里添加什么。 我认为
{}
将完整路径和文件名作为带有下划线的文件字符串提供,但我不知道如何使用类似
sed's/\ug'
的内容删除新文件名上的u。 任何帮助都将不胜感激。

请尝试:

find /Users/Chris/CDs -type f -name "*_*" -execdir bash -c 'mv -i -- "$1" "${1//_/}"' Mover  {} \;
工作原理:

  • -execdir bash-c'…'Mover{}

    这将启动bash并告诉它在单引号中运行命令,其中
    移动器
    分配给
    $0
    ,文件名分配给
    $1

  • mv-i--“$1”${1/}”

    这将重命名文件
    $1
    。这将使用bash的参数扩展特性
    ${1//\u/}
    ,通过删除所有下划线,从
    $1
    创建目标名称

    选项
    -i
    告诉
    mv
    在覆盖文件之前以交互方式询问

    选项
    --
    告诉
    mv
    没有更多选项。这是必需的,以便正确处理名称以
    -
    开头的文件

例子 让我们从包含以下文件的目录开始:

$ ls
1_2_3_4  a_b  c_d
接下来,我们运行命令:

$ find . -type f -name "*_*" -execdir bash -c 'mv -i -- "$1" "${1//_}"' Mover  {} \;
命令完成后,文件为:

$ ls
1234  ab  cd
$0的用途
请注意此命令,其中添加了一个错误:

$ find . -type f -name "*_*" -execdir bash -c 'foobar -i -- "$1" "${1//_}"' Mover  {} \;
Mover: foobar: command not found
请注意,
Mover
出现在错误消息的开头。这表示错误来自
bash-c
命令

如果我们用
-
替换
移动器
,我们将看到:

$ find . -type f -name "*_*" -execdir bash -c 'foobar -i -- "$1" "${1//_}"' -  {} \;
-: foobar: command not found

在终端中运行单个命令时,错误的来源可能仍然很明显。但是,如果这个
find
命令隐藏在一个长脚本中,那么使用更具描述性的
$0
,比如
Mover
或其他什么,可能会有很大帮助。

可能想使用
mv-i
来避免无意中覆盖任何文件。@willampersell非常好。我应该记得的。非常感谢。答案更新为
-i
。感谢您的回复。除了Mover{},我什么都跟着。@ChrisH
Mover
被分配给
$0
,文件名
{}
被分配给
$1
$0
不执行任何操作,除非
mv
命令生成错误,在这种情况下,shell将在脚本
Mover
中报告错误。因此,为
$0
选择一个描述性名称只会使错误消息(如果有的话)更具可读性。你可以使用任何你想要的名字。不关心信息性错误消息的人通常只使用
-
作为
$0
。我不熟悉bash,但对它的威力感到惊讶。感谢您的帮助,特别是深入的解释。
$ find . -type f -name "*_*" -execdir bash -c 'foobar -i -- "$1" "${1//_}"' -  {} \;
-: foobar: command not found