Я потратил почти полтора дня на это, но не смог найти ответ.
Я хочу добавить имя папки в качестве префикса для всех файлов, заканчивающихся на .bin в эта папка.
Итак, если имя папки ABC и содержит файлы aa.bin, bb.bin, cc.bin и т. д., тогда мне нужно, чтобы они были переименованы в ABC-aa.bin , ABC-bb.bin, ABC-cc.bin и т. д.
Кроме того, в этой папке ABC есть подпапки, назовем их: ABC1, ABC2, ABC3 и т. д., которые также имеют [ f14]. Например, ABC1 имеет aa1.bin, bb1.bin, cc1.bin и т. Д.
Мне нужна эта команда для просмотра всех папок и добавления этого имени подпапки в файлы внутри нее. Таким образом, aa1.bin будет ABC1-aa1.bin и т. Д.
Структура каталогов:
.
└── ABC
├── aa.bin
├── ABC1
│ ├── aa1.bin
│ └── bb1.bin
├── ABC2
│ ├── aa2.bin
│ └── bb2.bin
├── bb.bin
└── cc.bin
Вы можете сделать это, используя команды find, basename, dirname и mv. Например, как в этом простом скрипте:
#!/bin/bash
for f in $(find ABC -name '*.bin');
do
filename="$(basename $f)"
dir="$(dirname $f)"
lastdir="$(basename $dir)"
newname="$lastdir-$filename"
newpath="$dir/$newname"
mv $f $newpath
done
Здесь я использую find, чтобы рекурсивно найти все .bin файлы в ABC, затем перебрать их и извлечь последнее имя папки. Затем создается новый путь, и файл перемещается в тот же каталог, но с новым именем.
Редактировать. Чтобы выполнить этот скрипт, скопируйте его содержимое в некоторый файл. Скажем, имя файла renameFiles.sh. Затем сделайте его выполнимым:
chmod +x renameFiles.sh
После этого вы можете выполнить его с помощью ./renameFiles.sh. Обратите внимание, что папка, в которую вы помещаете этот файл, должна совпадать с вашей папкой ABC.
renameFiles.sh
ABC
aa.bin
bb.bin
ABC1
aa1.bin
etc.
Использование rename:
shopt -s globstar
rename -n '(! -f $_ || ! /.bin$/) && next; $" = "/"; my @f = split("/"); $f[@f-1] =~ s/^/$f[@f-2]-/; $_ = "@f"' **
shopt -s globstar: если установлено, шаблон «**», используемый в контексте расширения имени файла, будет соответствовать всем файлам и нулям или более каталогам и подкаталогам. Если за шаблоном следует '/', совпадают только каталоги и подкаталоги. rename -n '! -f $_ && next; $" = "/"; my @f = split("/"); $f[@f-1] =~ s/^/$f[@f-2]-/; $_ = "@f"' **: выполняет сухой пробег следующего. Для каждого имени файла, полученного в результате ** globbing: если файл не является обычным файлом или имя файла не заканчивается на .bin, пропускается следующее имя файла; устанавливает разделитель выходного поля на /; разбивает имя файла на /; добавляет второе к последнему поле, за которым следует - до последнего поля; присваивает новое имя файла переменной по умолчанию ($_). Если результат является ожидаемым, удалите параметр -n из команды rename.
$ tree
.
└── ABC
├── aa.bin
├── ABC1
│ ├── aa1.bin
│ └── bb1.bin
├── ABC2
│ ├── aa2.bin
│ └── bb2.bin
├── bb.bin
└── cc.bin
3 directories, 7 files
$ rename -n '(! -f $_ || ! /.bin$/) && next; $" = "/"; my @f = split("/"); $f[@f-1] =~ s/^/$f[@f-2]-/; $_ = "@f"' **
Exiting subroutine via next at (eval 4) line 1.
rename(ABC/aa.bin, ABC/ABC-aa.bin)
Exiting subroutine via next at (eval 4) line 1.
rename(ABC/ABC1/aa1.bin, ABC/ABC1/ABC1-aa1.bin)
rename(ABC/ABC1/bb1.bin, ABC/ABC1/ABC1-bb1.bin)
Exiting subroutine via next at (eval 4) line 1.
rename(ABC/ABC2/aa2.bin, ABC/ABC2/ABC2-aa2.bin)
rename(ABC/ABC2/bb2.bin, ABC/ABC2/ABC2-bb2.bin)
rename(ABC/bb.bin, ABC/ABC-bb.bin)
rename(ABC/cc.bin, ABC/ABC-cc.bin)