使用 find/xargs 命令根据其父目录重命名文件?

fdm*_*ion 5 bash find shell-script rename files

我有一个这样的目录结构:

Project/
  |
  +--Part1/
  |    |
  |    +--audio.mp3
  |
  +--Part2/
  |    |
  |    +--audio.mp3
  |
  +--Part3/
  |    |
  |    +--audio.mp3
...
Run Code Online (Sandbox Code Playgroud)

我想最终得到名为 Part1.mp3、Part2.mp3 等的文件。

每个文件夹只包含一个文件,因此不存在破坏文件或处理多个同名文件的风险。

我觉得我可以用某种find/xargs命令加上cutandmv但我无法弄清楚如何实际形成命令。

Rob*_*rtL 11

这些示例可在任何 POSIX shell 中运行,不需要外部程序。

这将 Part*.mp3 文件存储在与项目目录相同的级别:

(cd Project && for i in Part*/audio.mp3; do echo mv "$i" ../"${i%/*}".mp3; done)
Run Code Online (Sandbox Code Playgroud)

这会将 Part*.mp3 文件保留在项目目录中:

for i in Project/Part*/audio.mp3; do echo mv "$i" ./"${i%/*}".mp3; done
Run Code Online (Sandbox Code Playgroud)

这些解决方案使用 shellpattern matching parameter expansion来生成新的文件名。

 ${parameter%word}     Remove Smallest Suffix Pattern.  The word is expanded
                       to produce a pattern.  The parameter expansion then
                       results in parameter, with the smallest portion of
                       the suffix matched by the pattern deleted.
Run Code Online (Sandbox Code Playgroud)


roa*_*ima 7

如果您有 perl rename(有时称为prename),您可以这样做:

( cd Project && rename 's!(.+)/(.+)(\.mp3)!$1.$3!' */audio.mp3 )
Run Code Online (Sandbox Code Playgroud)

这将获取与 shell glob 匹配的每个文件*/audio.mp3名,并将其拆分为目录、文件名和扩展名组件。然后它丢弃文件名部分并重命名文件。

使用rename -n ...,看看会发生什么,或使用-v而不是-n看它的发生,因为它运行。


小智 1

你可以尝试这样的事情:

这些是您的文件:

$ cd Project
$ find . -type f
./Part2/audio.mp3
./Part3/audio.mp3
./Part1/audio.mp3
Run Code Online (Sandbox Code Playgroud)

使用dirname将返回其目录的名称(假设您只有一层子目录)。因此:

$ find . -type f \
   | while read i ; do \
       d=$(dirname $i); echo renaming "$i" to "$d.mp3" ; \
     done
renaming ./Part2/audio.mp3 to ./Part2.mp3
renaming ./Part3/audio.mp3 to ./Part3.mp3
renaming ./Part1/audio.mp3 to ./Part1.mp3
Run Code Online (Sandbox Code Playgroud)

这将重命名它们:

$ find . -type f | while read i ; do d=$(dirname $i); mv "$i" "$d.mp3" ; done
Run Code Online (Sandbox Code Playgroud)