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

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

Я надеюсь добавлять имя папки как префикс во все файлы, заканчивающиеся .bin в той папке.

Так, если имя папки ABC и это содержит файлы aa.bin, bb.bin, cc.bin, и т.д. затем мне нужны они, чтобы быть переименованным как ABC-aa.bin, ABC-bb.bin, ABC-cc.bin, и т.д.

Кроме того, эта папка ABC имеет подпапки, давайте назовем их: ABC1, ABC2, ABC3, и т.д., которые также имеют .bin файлы. Например, 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 в 21:58

3 ответа

Вот "острота", чтобы сделать, с помощью оболочки, созданной-ins для управления именами файлов:

find . -name '*.bin' -exec sh -c 'p="${1%/*}"; f="${1##*/}"; echo mv -- "$1" "$p/${p##*/}-$f"' sh {} \;

Тест это в целевом каталоге и удаляет echo, если результаты выглядят корректными

, например, учитывая

$ tree .
.
└── ABC
    ├── aa.bin
    ├── ABC1
    │   ├── aa1.bin
    │   └── bb1.bin
    ├── ABC2
    │   ├── aa2.bin
    │   └── bb2.bin
    ├── bb.bin
    └── cc.bin

3 directories, 7 files

затем

$ find . -name '*.bin' -exec sh -c 'p="${1%/*}"; f="${1##*/}"; echo mv -- "$1" "$p/${p##*/}-$f"' sh {} \;
mv -- ./ABC/ABC2/bb2.bin ./ABC/ABC2/ABC2-bb2.bin
mv -- ./ABC/ABC2/aa2.bin ./ABC/ABC2/ABC2-aa2.bin
mv -- ./ABC/aa.bin ./ABC/ABC-aa.bin
mv -- ./ABC/bb.bin ./ABC/ABC-bb.bin
mv -- ./ABC/ABC1/bb1.bin ./ABC/ABC1/ABC1-bb1.bin
mv -- ./ABC/ABC1/aa1.bin ./ABC/ABC1/ABC1-aa1.bin
mv -- ./ABC/cc.bin ./ABC/ABC-cc.bin

хорошие взгляды, поэтому удалите echo и выполните его снова

$ find . -name '*.bin' -exec sh -c 'p="${1%/*}"; f="${1##*/}"; mv -- "$1" "$p/${p##*/}-$f"' sh {} \;

предоставление

$ tree .
.
└── ABC
    ├── ABC1
    │   ├── ABC1-aa1.bin
    │   └── ABC1-bb1.bin
    ├── ABC2
    │   ├── ABC2-aa2.bin
    │   └── ABC2-bb2.bin
    ├── ABC-aa.bin
    ├── ABC-bb.bin
    └── ABC-cc.bin

3 directories, 7 files
1
ответ дан 7 December 2019 в 13:48

Можно сделать это при помощи 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

Здесь я использую, находят, чтобы рекурсивно найти весь .bin файлы в ABC, затем выполнить итерации по ним и извлечению последнего имени папки. Затем новый путь создается, и файл перемещен в тот же каталог, но с новым именем.

Редактирование :
для выполнения этого сценария, копируют его содержание в некоторый файл. Скажем, имя файла renameFiles.sh. Затем сделайте это исполняемым файлом:

chmod +x renameFiles.sh

После этого можно выполнить его с ./renameFiles.sh. Заметьте, что папка, куда Вы помещаете этот файл, должна быть тем же, где Ваша папка ABC расположена.

renameFiles.sh
ABC
  aa.bin
  bb.bin
  ABC1
    aa1.bin
    etc.
1
ответ дан 7 December 2019 в 13:48

Используя 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
ответ дан 7 December 2019 в 13:48

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

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