Переименовать определенные файлы с частью имени родительского каталога

Я хотел бы идентифицировать файлы, которые удовлетворяют определенным строковым критериям в подкаталогах, а затем переименовывать эти файлы с последней частью имени каталога, 2 каталогами вверх («pd1»?), Тогда я хотел бы переместить все переименованные файлы в отдельный каталог.

Более подробно: скажем, я запускаю гипотетический код из каталога /x/y/z и в этом каталоге находятся каталоги с именами типа « 20150416_110508_3006 ». Файлы, которые я хочу переименовать, находятся в (пример) ' /x/y/z/20150416_110508_3006/dicom ', например, имя файла ' o20150416_110508MPRAGESAGs002a1001.nii '. Важные элементы имени файла, необходимые для его отличия от похожих файлов, – это префикс « o », « s002a » в середине и расширение « .nii ».

Я хотел переименовать эти файлы с последней частью каталога pd1, в данном случае « 3006 », поэтому « 3006.nii ». Затем, выполнив это для всех применимых файлов, я хотел бы переместить переименованные файлы в каталог в ' /x/y/z '.

С zsh :

 autoload zmv # best in ~/.zshrc zmv -n '/x/y/z/*_*_(*)/dicom/o*s002a*.nii' '${f:h}/$1.nii' 

Или:

 zmv -n '/x/y/z/*_*_(*)/dicom/o*s002a*.nii' '/x/y/z/somedir/$1.nii' 

Чтобы переместить их в somedir в /x/y/z .

Удалите -n чтобы на самом деле сделать переименование, после того как вы удовлетворены, он делает то, что вы хотите.

zmv обнаружил бы конфликтующие переименования до начала любого из переименований. Выполнение чего-то подобного с другими оболочками, такими как bash , потребует более длинного скрипта. Что-то вроде:

 #! /bin/bash - typeset -A seen shopt -s nullglob for file in /x/y/z/*_*_*/dicom/o*s002a*.nii; do tag=${file%/*/*} tag=${tag##*_} if [[ ${seen[$tag]} ]]; then printf >&2 '"%s" and "%s" both map to "%s"\n' "$file" "${seen[$tag]}" "$tag" exit 1 fi seen[$tag]=$file done for tag in "${!seen[@]}"; do echo mv -i -- "${seen[$tag]}" "/x/y/z/somedir/$tag" done 

(Непроверенные)

(удалите echo для выполнения переименования).

Обратите внимание, что ассоциативные массивы bash (в отличие от ksh93 или zsh) имеют ошибку / ограничение в том, что вы не можете иметь элементы с пустым ключом. Поэтому, если у вас есть foo_bar_/dicom/*.nii , это не сработает должным образом, поэтому даже для этого программного подхода я бы все же пошел с zsh или ksh93 вместо bash .