Добавьте имя папки во все файлы `.bin` в этой папке

Я потратил почти полтора дня на это, но не смог найти ответ.

Я хочу добавить имя папки в качестве префикса для всех файлов, заканчивающихся на .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
1
задан 8 February 2016 в 22:58

2 ответа

Вы можете сделать это, используя команды 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.
1
ответ дан 23 May 2018 в 13:40
  • 1
    Я совершенно не знаком с Linux. Не знаю, как использовать «для» вещи .. извините, если вы расстроены этим ... Когда я вхожу! / Bin / bash в терминал, я получаю ошибку ... (событие не найдено) .. ищет исправить это, BTW. – Krishna 8 February 2016 в 21:16
  • 2
    Я обновил ответ так, надеюсь, теперь его ясно. – incBrain 8 February 2016 в 21:33
  • 3
    Я исследовал его и узнал. Точно как вы направляете. Это и сейчас все в порядке. Благодаря тонну!! – Krishna 8 February 2016 в 21:50

Использование 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)
0
ответ дан 23 May 2018 в 13:40
  • 1
    Это замечательная команда ... но как ограничить ее только битными файлами? Благодаря! То, что он (уже) исключает каталоги и подкаталоги тоже хорошо. – Krishna 8 February 2016 в 22:42
  • 2
    @ user3647217 Справедливо, не думал, что переименовал бы даже файлы, не заканчивающиеся на .bin, отредактировал ответ. Попробуйте это вместо: rename -n '(! -f $_ || ! /.bin$/) && next; $" = "/"; my @f = split("/"); $f[@f-1] =~ s/^/$f[@f-2]-/; $_ = "@f"' **. – kos 8 February 2016 в 22:49

Другие вопросы по тегам:

Похожие вопросы: