Рекурсивное переименование папок и файлов в имя подкаталога и перемещение файлов

У меня есть несколько подкаталогов без единого образца именования в моем домашнем каталоге (например, ~/123, ~/456, ~/789).

В каждом из этих подкаталогов у меня есть две папки с именами alignment1 и alignment2. В папках alignment1 и alignment2 есть несколько файлов.

Интересующие меня файлы имеют имена alignment1 (без расширения) в папке alignment1 и файл alignment2 (без расширения) в папке alignment2.

Помните, что в папках alignment1 и alignment2 есть другие файлы с именами alignment, , но у них есть расширения (например, alignment1.backbone, alignment1.bbcol и alignment2.backbone, alignment2.bbcol в соответствующих папках alignment1 и alignment2), но я < em> не интересуются этими файлами.

~/123/alignment1/alignment1
~/123/alignment2/alignment2
~/456/alignment1/alignment1
~/456/alignment2/alignment2
etc...

Вопрос:

  1. Моя борьба состоит в том, чтобы переименовать папки alignment1 и alignment2 в subdirectory_alignment1 и subdirectory_alignment2 (например, 123_alignment1 и 123_alignment2).

  2. Затем в папках alignment1 и alignment2 файлы выравнивания, названные alignment1 и alignment2 соответственно, необходимо переименовать в subdirectory_1.aln и subdirectory_2.aln.

  3. Переместите subdirectory_1.aln и subdirectory_2.aln в домашний каталог.

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


person Abi    schedule 29.01.2016    source источник


Ответы (1)


Пытаемся разбить проблему на мелкие части. Этот фрагмент кода должен найти все вхождения. Возможно, вам стоит что-то изменить в регулярном выражении. \1 будет соответствовать тому, что уже совпало внутри \( и \). mindepth должен найти */*/* и ниже. * здесь важен из-за количества /, которое вы получите в результате.

find * -mindepth 2 -type f | grep '/\([a-z]*[0-9]\)/\1' | while read f; do
  <process>
done

Теперь вы перебираете все интересующие вас файлы. echo "$f" внутри цикла - хорошая идея, прежде чем двигаться дальше.

Если фильтр работает, вот несколько идей, как разбить имя файла на мелкие части:

d1=`cut -d'/' -f1 <<< "$f"`
d2=`cut -d'/' -f2 <<< "$f"`
newName="${d1}/${d1}_${d2}"

А теперь просто несколько простых mv "$from" "$to" здесь и там.

person Joao Morais    schedule 29.01.2016
comment
Извините, но код, похоже, у меня не работает. Я пробовал использовать echo $ f, но совпадений не найдено. Я думаю, что даже find не находит файлы -: .. Я знаю, что здесь я не помогу, так как нет сообщения об ошибке, к которому можно было бы относиться .. Любые мысли? - person Abi; 29.01.2016
comment
@Abi Попробуйте найти только * -mindepth 2 -type f (из корневого каталога вашего поиска), упростите grep. Хитрость здесь в том, чтобы создавать сценарий по частям. - person Joao Morais; 29.01.2016
comment
Итак, вот как далеко я зашел; найти . -name alignment1 | sed 's #. / ([A-Za-z0-9 _-] *) / alignment1 # mv \ 1 / alignment1 \ 1 / \ 1_alignment1 #'. Этот код переименовывает папку alignment1 в subdirectory_alignment1, но, как вы сказали, находит все вхождения alignment1, включая файлы alignment1. Я не могу заставить его распознавать только выравнивание папки1. Вы можете придумать поправку? - person Abi; 29.01.2016
comment
Я использовал выборочные команды, которые он печатает, чтобы переименовать alignment1 в subdirectory_alignment1, НО мне не удалось изменить сценарий для переименования файлов alignment1, теперь в папке subdirectory_alignment1 в subdirectory_alignment1.aln .. Любая идея? - person Abi; 29.01.2016
comment
Дальнейшее развитие; теперь эту командную строку найди. -name alignment1 | sed 's #. / ([A-Za-z0-9] *) / alignment1 # mv \ 1 / alignment1 \ 1 / \ 1.aln #' находит файл alignment1 в subdirectory_alignment1, но часть mv его не работает?? - person Abi; 29.01.2016
comment
@Abi, я думаю, одно решение - egrep '/ (ab) / \ 1', которое будет соответствовать / ab / ab, но не / ab / cd. Не знаю вашего дерева каталогов, но мне кажется, что find -type f (и без -name) | grep - это то, что вам нужно. Более того: вы не можете использовать mv внутри sed; используйте синтаксис | пока читал f; сделать (на мой ответ), чтобы перебрать имена файлов. - person Joao Morais; 29.01.2016