【问题标题】:More idiomatic BASH script for multi-folder file rename用于多文件夹文件重命名的更多惯用 BASH 脚本
【发布时间】:2014-12-15 12:36:56
【问题描述】:

我目前正在使用一堆单行代码来重命名 bash 中生成的图标文件。

for f in black/*.png ; do mv $f "${f%%.png}_black.png" ; done
for f in blue/*.png ; do mv $f "${f%%.png}_blue.png" ; done
for f in brown/*.png ; do mv $f "${f%%.png}_brown.png" ; done
for f in green/*.png ; do mv $f "${f%%.png}_green.png" ; done
for f in grey/*.png ; do mv $f "${f%%.png}_grey.png" ; done
for f in red/*.png ; do mv $f "${f%%.png}_red.png" ; done
for f in white/*.png ; do mv $f "${f%%.png}_white.png" ; done
for f in yellow/*.png ; do mv $f "${f%%.png}_yellow.png" ; done

但是男孩是啰嗦。鉴于文件夹结构,我可以使用更惯用 BASH 的单行版本吗?我只是想知道我是否错过了一个技巧。

我在 Mac OS X Darwin 命令行上运行,所以没有 renameprename :-( 并且更喜欢纯 bash。

-- 编辑

所以它不会在 cmets 中迷失 - Tim Zimmerman 的回答是单行的:

for d in */; do for f in $d*.png ; do mv "$f" "${f%%.png}_${d%%/}.png" ; done ; done

${f%%.png}_${d%%/}.png 中进行第二次重命名是一个让我难过的技巧。

【问题讨论】:

  • 是的,我可以,除非问题中提到,在香草 MacOS X Darwin 上似乎没有 rename

标签: bash rename idioms


【解决方案1】:

如果您的子目录中没有包含 *.png 文件的子目录,除了您想要移动的文件,您可以这样做

for f in */*.png; do
    d=${f%/*}
    b=${f#*/}
    mv "$f" "${b%.png}_$d.png"
done

如果您不坚持当前的命名约定,您甚至可以这样做

for f in */*.png; do
    mv "$f" "${f/\//_}"
done

如果你愿意,它不难变成真正的单线。 (所以这基本上是用下划线替换第一个斜线。)

【讨论】:

    【解决方案2】:
    for c in black blue brown; do
      for f in $c/*.png ; do mv "$f" "${f%%.png}_$c.png" ; done
    done
    

    for f in {black,blue,brown}/*.png; do mv "$f" "${f%%.png}_${f%/*}.png" ; done
    

    【讨论】:

      【解决方案3】:

      您可以循环遍历所有子目录并再次使用目录名称来重命名文件:

      #!/bin/bash
      
      for d in */; do
          for f in "$d"*.png; do
              mv "$f" "${f%%.png}_${d%%/}.png"
          done
      done
      

      请注意,$d 包含 /,因此必须在重命名时将其删除。

      【讨论】:

      • 该数组并不是真正有用,因为您只引用它一次。 for d in black blue brown green grey red white yellow; do...
      • 所以鉴于我在父文件夹中,我可以使用 do for d in `ls -p | grep /` 吗?
      • 您使用 glob 是正确的;不要解析ls的输出。
      • 您可以只使用for d in */; do 来确保您只迭代目录。不需要if 声明。
      • 就像@chepner 所说,不要解析ls (mywiki.wooledge.org/ParsingLs) 的输出。但是,您可以测试目录。我更新了我的答案以遍历当前目录的所有子目录。
      猜你喜欢
      • 1970-01-01
      • 2011-12-25
      • 2011-06-19
      • 2014-05-01
      • 2013-06-10
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多