将文件夹移动到 unix 中按字母顺序排列的子目录

Moving folders into alphabetised sub directories in unix

给定一个包含公司名称的文件夹:

Ace inc
Austerity
A to Z
Beeline Industries
Bing
Booze inc.
Crypto
....
Zeebra 

...我需要将所有 A* 文件夹移动到子目录 A:

A/Ace inc
A/Austerity
A/A to Z
...

我尝试了以下命令:mv A* /A/ 一直运行到某个点,然后失败,因为它试图将新创建的 A/ 移动到自身中。

此外 - 我觉得 运行 这个命令已经用过一次了,我可能把我们的文件系统搞得一团糟。

您想在开始移动之前创建一个文件名列表。你不应该能够写信给 /... 除非你是 运行 作为 SuperUserroot,所以你不应该打任何东西(你很可能把包含原始文件的子目录搞得一团糟...)

要在当前目录中创建一个文件列表并逐一循环,您可以简单地使用 for fname in *; do ... done。您将需要引用所有后续使用的 fname 以防止分词。由于您还标记了问题 shell 而不是 bash 等,因此您需要使用符合 POSIX 的方式来获取每个问题的第一个字符 (fc)文件名。为此,您可以在命令替换中使用旧的 expr substr "$fname" 1 1,例如

    fc=$(expr substr "$fname" 1 1)  ## use 'expr substr ...' to get 1st char

将其完全放在一个 POSIX 兼容的 shell 脚本中,该脚本仅对当前目录中的文件进行操作,根据文件名的第一个字符将当前目录中的所有文件移动到适当的子目录中,你可以这样做:

#!/bin/sh

for fname in *; do                  ## loop over each file
    [ -d "$fname" ] && continue     ## skip all directory names
    fc=$(expr substr "$fname" 1 1)  ## use 'expr substr ...' to get 1st char
    mkdir -p "$fc" || exit 1        ## create the directory or exit
    mv "$fname" "$fc" || exit 1     ## move the file or exit
done

生成的目录结构

使用您在示例列表中提供的文件名将产生以下目录结构:

$ tree .
.
├── A
│   ├── A to Z
│   ├── Ace inc
│   └── Austerity
├── B
│   ├── Beeline Industries
│   ├── Bing
│   └── Booze inc.
├── C
│   └── Crypto
└── Z
    └── Zeebra

如果您在修复文件系统方面需要帮助,您需要在其他 StackExchange 站点 Super User or Unix & Linux 上询问该问题,因为它与 "Programming" 无关。

如果你有 bash 或其他一些支持字符串索引作为参数扩展的 shell,那么使用它来获取第一个字符会更快并且避免 subshell 命令替换需要 $(expr ...)

如果您对将文件移动到子目录有更多疑问,请告诉我。

根据不移动当前目录中的文件的说明进行编辑

好的,如果我们达成这样的理解:(1) 你是 运行 bash 作为你的 shell,(2) 你不想移动 files 在当前目录下的子目录下,并且 (3) 只想将工作目录中包含的 directories(及其内容)移动到第一个创建的目录下目录名称的字符,您可以在下面进行以下更改:

#!/bin/bash

for fname in *; do                  ## loop over each file
    [ -f "$fname" ] && continue     ## skip files in the current dir
    fc=${fname:0:1}                 ## use parameter expansion for 1st char
    mkdir -p "$fc" || exit 1        ## create the directory or exit
    [ "$fc" = "$fname" ] && continue    ## don't move dir into itself
    mv "$fname" "$fc" || exit 1     ## move the directory or exit
done

原始目录结构

当前目录中的脚本示例以及 ApplesCans 的其他目录包含需要移动到 'A''C' 目录下的文件,分别为:

$ tree .
.
├── A
│   ├── A to Z
│   ├── Ace inc
│   └── Austerity
├── Apples
│   ├── file1
│   └── file2.3
├── B
│   ├── Beeline Industries
│   ├── Bing
│   └── Booze inc.
├── C
│   └── Crypto
├── Cans
│   ├── file1
│   ├── file2
│   └── file3
├── Z
│   └── Zeebra
└── script.sh

示例使用

$ bash script.sh

生成的目录结构

$ tree .
.
├── A
│   ├── A to Z
│   ├── Ace inc
│   ├── Apples
│   │   ├── file1
│   │   └── file2.3
│   └── Austerity
├── B
│   ├── Beeline Industries
│   ├── Bing
│   └── Booze inc.
├── C
│   ├── Cans
│   │   ├── file1
│   │   ├── file2
│   │   └── file3
│   └── Crypto
├── Z
│   └── Zeebra
└── script.sh

仔细检查一下,如果我们就您需要完成的工作达成一致意见,请告诉我。

我对脚本做了一些修改,以防止尝试将文件夹 A 嵌套在自身内部,expr 导致语法错误。

#!/bin/sh

for fname in *; do
if [ ${#fname} -gt 1 ]; then
    fc=$(echo $fname | head -c 1)
    mkdir -p "$fc" || exit 1
    mv "$fname" "$fc" || exit 1
fi
done