我如何 move/group bash 中的特定文件夹?

How can i move/group specific folders in bash?

我的文件夹结构如下:

2020-123-1
2020-123-2
2020-123-3
2020-124-1
2020-124-2
...

我需要根据前 2 个数字创建文件夹并省略第二个破折号 (-) 后面的内容。然后我需要将之前的文件夹以正确的名称放在新创建的文件夹下。

2020-123
        ->2020-123-1
        ->2020-123-2
        ->2020-123-3
2020-124
        ->2020-124-1
        ->2020-124-2

我试过在 bash 中编写这样的脚本:

ls -d */ > folder.txt
cut -f1,2 -d"-" folder.txt |cut -f1 -d"/" |sort|uniq  > mainfolder.txt
while read line; do mkdir $line ; done < mainfolder.txt 
while read line; do mv $(cut -f1,2 -d"-" $line) $line/ ; done < folder.txt

我无法使最后一行工作,我知道它有问题。

实际上,您不必解析目录名称并构建层次结构。您可以使用 mkdir-p 选项,因此,一个 awk 一行就可以完成这项工作:

awk -F'-' '{top= FS ;printf "mkdir -p %s; mv %s %s\n",top, [=10=], top}' dir.txt

您的示例的输出:

mkdir -p 2020-123; mv 2020-123-1 2020-123
mkdir -p 2020-123; mv 2020-123-2 2020-123
mkdir -p 2020-123; mv 2020-123-3 2020-123
mkdir -p 2020-124; mv 2020-124-1 2020-124
mkdir -p 2020-124; mv 2020-124-2 2020-124

备注

  • 这一行只打印命令而不执行它们,如果一切正常,您只需将输出通过管道传输到 |sh。检查输出命令,更改printf format/values 进行调整。
  • 我没有引用文件名,因为您的示例不包含任何特殊字符。有的话就去做

所以最终的脚本如下:

ls -d */ | cut -f1 -d"/" > folder.txt
awk -F'-' '{top= FS ;printf "mkdir -p %s; mv %s %s\n",top, [=10=], top}' folder.txt |sh

纯bash:

#!/bin/bash

for src in *-*-*; do
    destdir=${src%-*}
    [[ -d $destdir ]] || mkdir "$destdir" || exit
    # This just prints out the command that will be called.
    # Remove the "echo" in actual script after making sure it will run as intented
    echo mv "$src" "$destdir"
done

在上面的脚本中,假设要移动的每个文件名都恰好包含两个破折号。如果它可以包含两个 或更多 破折号,则 destdir=${src%-*} 行应替换为以下两行:

suffix=${src#*-*-}
destdir=${src%"-$suffix"}

有关详细信息,请阅读 "shell parameter expansion" section in bash reference

此外,值得一读的文章是:Why you shouldn't parse the output of ls