【问题标题】:Interweave contents of two directories into a new directory将两个目录的内容交织到一个新目录中
【发布时间】:2017-07-20 00:16:55
【问题描述】:

我有两个具有连续内容的目录(即,内容的文件名是 001.jpg、002.jpg、003.jpg 等等,最多 1000 个文件)。我想将它们以交替顺序合并到一个新目录中,如下所示:

Dir1
├── 001.jpg
├── 002.jpg
├── 003.jpg
└── 004.jpg
Dir2
├── 002.jpg
├── 003.jpg
├── 004.jpg
└── 005.jpg

OutputDir
├── 001.jpg (001.jpg from Dir1)
├── 002.jpg (002.jpg from Dir2)
├── 003.jpg (002.jpg from Dir1)
├── 004.jpg (003.jpg from Dir2)
├── 005.jpg (003.jpg from Dir1)
├── 006.jpg (004.jpg from Dir2)
├── 007.jpg (004.jpg from Dir1)
└── 008.jpg (005.jpg from Dir2)

这是我所拥有的,但它依赖于两个具有相同名称的目录:

cp Dir1/* OutputDir/
cp --backup=existing --suffix=.2 Dir2/* OutputDir/
cd OutputDir
# next line from here: https://stackoverflow.com/questions/3211595/renaming-files-in-a-folder-to-sequential-numbers
ls | cat -n | while read n f; do mv "$f" "$n.jpg"; done

我希望有一个不依赖于两个目录的文件名相同的解决方案。

【问题讨论】:

    标签: bash


    【解决方案1】:

    这是一种方法。

    #! /bin/bash
    a=(Dir1/*)
    b=(Dir2/*)
    for ((i=0;i<${#a[@]};++i)); do
      mv "${a[i]}" "OutputDir/$(printf '%03d.jpg' "$((2*i+1))")"
      mv "${b[i]}" "OutputDir/$(printf '%03d.jpg' "$((2*i+2))")"
    done
    

    它确实假设 Dir1 和 Dir2 中的文件数量相同,但您的示例暗示这是真的。

    【讨论】:

    • 您可能想用ls 完全删除命令替换,只允许globbing 填充数组。但是,你和 ghoti 都获得了几乎同时回答的投票 :) 我仍然对哪个文件获得下一个序列号逻辑(或缺少)的逻辑感到困惑。
    • 非常感谢。完成。
    • 我忘了说明,但是是的,两个目录都有相同数量的文件。
    • @RobinAnupol 没问题。注意我添加了引号iaw最佳实践。如果文件名包含 shell 将重新解释的字符,它们就很重要。
    【解决方案2】:

    假设两个输入目录中的文件数量相同,您可以简单地遍历数组索引,如下所示:

    #!/usr/bin/env bash
    
    a=(Dir1/*.jpg)
    b=(Dir2/*.jpg)
    n=1
    
    for i in "${!a[@]}"; do
        mv "${a[$i]}" "OutputDir/$( printf '%03d' $n ).jpg"
        ((n++))
        mv "${b[$i]}" "OutputDir/$( printf '%03d' $n ).jpg"
        ((n++))
    done
    

    如果他们有可能拥有不同数量的文件,您需要为此定义行为并编写一些东西来处理它。也许是这样:

    #!/usr/bin/env bash
    
    a=(Dir1/*.jpg)
    b=(Dir2/*.jpg)
    
    if [[ ${#a[@]} -gt ${#b[@]} ]]; then
            c=( ${!a[@]} )
    else
            c=( ${!b[@]} )
    fi
    
    n=1
    
    for i in "${c[@]}"; do
        echo "i=$i"
        [[ -f "${a[$i]}" ]] &&
          mv -v "${a[$i]}" "OutputDir/$( printf '%03d' $n ).jpg" && ((n++))
        [[ -f "${b[$i]}" ]] &&
          mv -v "${b[$i]}" "OutputDir/$( printf '%03d' $n ).jpg" && ((n++))
    done
    

    使用此解决方案,如果一个目录的文件多于另一个目录,则其文件应按照相同的计数器顺序附加到 OutputDir。请注意,((n++)) 仅在移动成功时执行,这应确保您的输出文件是连续的,没有中断。

    这里的依赖是数组索引必须是连续的,没有中断。

    【讨论】:

    • 锦上添花的是((n &gt;= 1000)) &amp;&amp; break:)
    • 如果我可以投票两次——那就值两倍。就像我对 Gene 评论的那样,当你们俩都回答时,我仍在试图弄清楚如何排序哪个文件得到哪个数字。干得好:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 2015-09-12
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2014-10-16
    相关资源
    最近更新 更多