【问题标题】:Unix CLI script to rename folders using their pre-existing namesUnix CLI 脚本使用其预先存在的名称重命名文件夹
【发布时间】:2012-09-05 21:42:41
【问题描述】:

我有一个文件夹结构如下的目录:

-- DATA -- ABD 1231345 -- 01-08-12 // date in mm-dd-yy format
                       -- 03-09-12
                       -- 06-11-12

        -- DEF 4859480 -- 02-10-12
                       -- 05-10-12
                       -- 07-10-12

我想批量重命名这个DATA文件夹如下

-- DATA -- ABD 1231345 -- 2012_01_08 // date in yyyy_mm_dd format with underscore
                       -- 2012_03_09
                       -- 2012_06_11

        -- DEF 4859480 -- 2012_02_10
                       -- 2012_05_10
                       -- 2012_07_10

您对如何在 Mac OSX / unix 上使用命令行完成有什么建议吗?

【问题讨论】:

    标签: regex bash unix rename


    【解决方案1】:

    您可以使用for 循环和awk,将每个文件名解析为您指定的格式,然后mv 将原始文件名重命名为新名称:

    for dir in DATA/*; do \
        pushd "$dir"; # change directory \
        for file in *; do \
            path=`echo $file | awk -F- '{print "20"$3"_"$1"_"$2}'`; \
            mv $file $path; # "rename" the file \
        done; \
        popd; # restore original directory \
    done;
    

    这可以在DATA上方的文件夹中执行。如果您想直接在DATA 中执行它,请将第一个循环更新为读取for dir in *; do 而不是DATA/*。它告诉awk 使用- 作为分隔符(而不是空格),然后将字符串从“mm-dd-yy”重构为“20yy_mm_dd”。

    使用pushdpopd 将使脚本能够将当前目录更改为DATA (pushd) 内的每个子目录,然后在移动所有必要的文件后将更改回原始目录(popd )。这样做将为您节省大量尝试保存目录路径 / 等的解析工作。

    【讨论】:

    • 我刚刚注意到,如果我在父文件夹 /DATA 中,我无法运行您的解决方案 - 只有在我处于下一个级别 ABD 1231345 时它才有效 - 我怎样才能获得您的代码在没有cd'ing 进入每个第一个子文件夹的情况下工作?
    • @torr 更新为遍历目录;我使用pushdpopd 这样做 - chepner 和 Mat 的答案(后者通过这些命令链接到另一个问题)中提到了这两者,而不是字符串操作以节省头痛 =]
    • 我遇到的一个问题是文件夹在ABD123143 之间有一个空格——例如ABD 12314435。这导致脚本失败,因为它似乎只在空格之前获取文件夹名称 - 所以我收到多条消息,如 -bash: pushd: ./ABD: No such file or directory
    • @torr 对不起,我早该预料到的;尝试在pushd "$dir"; 周围添加双引号(我也更新了答案以显示)。
    【解决方案2】:

    使用date命令转换文件名:

    $ date -j -f %m-%d-%y 01-08-12 +%Y_%m_%d
    2012_01_08
    

    获取文件有点小技巧。我们将只切换目录以避免处理长文件路径。

    for d in DATA; do
        pushd "$d"
        for f in *; do
            new_f=$(date -j -f %m-%d-%y $f +%Y_%m_%d)
            mv "$f" "$new_f"
        done
        popd
    done
    

    【讨论】:

      【解决方案3】:

      您可以使用 string manipulationsarrays 仅对 bash 执行此操作。

      类似:

      for f in * ; do
        parts=(${f//-/ })
        mv "$f" "20${parts[2]}_${parts[1]}_${parts[0]}"
      done
      

      在此站点中搜索各种选项以递归到目录中,例如: Shell script to traverse directories

      【讨论】:

        【解决方案4】:

        This site 给出了很好的 sn-p

        for i in *.avi; do j=`echo $i | sed 's/(\d{2})-(\d{2})-(\d{2})/20\3_\1_\2/g'`; mv "$i" "$j"; done
        

        【讨论】:

          猜你喜欢
          • 2012-09-07
          • 2015-10-22
          • 2020-06-29
          • 2015-02-25
          • 2014-08-03
          • 1970-01-01
          • 2020-05-28
          • 2014-12-27
          • 1970-01-01
          相关资源
          最近更新 更多