Перемещение папок в алфавитные подкаталоги в Unix - PullRequest
0 голосов
/ 30 апреля 2019

Учитывая папку с названиями компаний:

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 ]

2 голосов
/ 30 апреля 2019

Вы хотите создать список имен файлов, прежде чем начать движение. Вы не должны были бы писать в /..., если только вы не работали как 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-совместимый сценарий оболочки, который работает только с файлами в текущем каталоге, перемещая все файлы в текущем каталоге в соответствующий подкаталог на основе первого символа имени файла, вы можете сделать:

#!/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 Суперпользователь или Unix & Linux , поскольку это не связано с "Программированием".

Если у вас есть bash или какая-либо другая оболочка, которая поддерживает строковые индексы в качестве раскрытия параметра, то использование этого для получения первого символа будет быстрее и позволит избежать подоболочки, необходимой для подстановки команды с $(expr ...)

Сообщите мне, если у вас есть дополнительные вопросы по перемещению файлов в подкаталоги.

Редактировать на основе разъяснений, чтобы не перемещать файлы в текущем каталоге

ОК, если мы достигли понимания, что (1) вы используете bash в качестве оболочки, (2) вы не хотите перемещать файлы в текущем каталоге, под подкаталогами, и (3) только для перемещения каталогов , содержащихся в рабочем каталоге (с их содержимым) ниже каталогов, созданных из первого символа имени каталога, вы можете внести следующие изменения ниже:

#!/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

Результирующая структура каталогов

$ 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

Посмотрите это и дайте мне знать, если у нас было совещание о том, что вам нужно сделать.

0 голосов
/ 30 апреля 2019

Я немного изменил сценарий, чтобы предотвратить попытки вложить папку 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
...