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

时间:2019-04-29 23:03:39

标签: linux unix subdirectory mv

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

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/移入自身。

进一步-我觉得已经运行过此命令一次,可能使我们的文件系统混乱了。

2 个答案:

答案 0 :(得分:2)

您要在开始移动之前创建文件名列表。除非您以 SuperUser /...的身份运行,否则您不应该写root,因此,您不应对任何内容进行任何改动(您可能已经做了包含原始文件的子目录一团糟...)

要在当前目录中创建文件列表并一个接一个地循环,只需使用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 UserUnix & Linux上询问该问题,因为它与“编程”无关。

如果您有bash或其他一些支持string-indexes作为参数扩展的shell,那么使用它来获取第一个字符会更快,并且避免了用{{1 }}

如果您对将文件移至子目录还有其他疑问,请与我联系。

基于说明进行编辑以不移动当前目录中的文件

好吧,如果我们已经了解到(1)您正在运行$(expr ...)作为shell,(2)您不想将文件移动到下面的当前目录中子目录,以及(3)只想将工作目录中包含的目录(及其内容)移动到从目录名的第一个字符创建的目录下,您可以在下面进行以下更改:

bash

原始目录结构

一个示例,其中脚本位于当前目录中,另外的目录#!/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 Apples包含需要分别移至Cans'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

仔细研究一下,让我知道我们是否就您需要完成的事情进行了座谈。

答案 1 :(得分:0)

我对脚本进行了一些修改,以防止尝试将文件夹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