Рейтинг:2

Найти все файлы с заданным расширением в подпапках и добавить подстроку, соответствующую подпапке

флаг cn

у меня много текст файлы, разбросанные по разным папкам.

- Дело 1
   |
    - 0,25
       |
        - case1.txt
    - 0,35
       |
        _ case1.txt
    - 0,30
       |
        _ case1.txt
    - 0,45
       |
        _ case1.txt

- case2
   |
    - 0,25
       |
        - case2.txt
    - 0,35
       |
        _ case2.txt
    - 0,30
       |
        _ case2.txt
    - 0,45
       |
        _ case2.txt

.
.
.

Я хотел бы скопировать их все в папку, но, к сожалению, как видите, некоторые из них имеют одно и то же имя, а значит, наивный найти решение в конечном итоге перезаписывает их. Я хотел бы скопировать все текст файлы в каталог фу, вставив имя подпапки, в которой они находятся, перед .текст расширение. Также, так как в названии подпапки стоит точка, и мне нужно скопировать эти файлы в винду, я бы тоже хотел изменить 0.25 к 0_25. Другими словами, файл

- case2
   |
    - 0,25
       |
        - case2.txt

необходимо скопировать в фу как case2_0_25.txt. Если решение bash слишком сложное/нечитаемое, решение Python тоже подойдет, но нет зш один.

Рейтинг:3
флаг cn

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

шопт -с глобстар; \
tar -cvf --show-transformed-names --transform='s![.]!_!g' --transform='s!.*/\([^/]\+\)/\([ ^/]\+\)_txt$!foo/\2_\1.txt!' case*/**/*.txt | смола -xf-

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

Решение Bash будет работать почти так же.

#!/бин/баш

shopt -s nullglob глобстар

mkdir -p foo
при чтении -rd ''; делать
    [[ ${REPLY//./_} =~ ([^/]+)/([^/]+)_txt$ ]] && 
        cp -va "$REPLY" "foo/${BASH_REMATCH[2]}_${BASH_REMATCH[1]}.txt"
сделано < <(printf %s\0 case*/**/*.txt)
Рейтинг:2
флаг cn

Вы можете сделать это достаточно легко, используя опцию bash globstar (из человек):

глобус

Если установлено, шаблон ** используемый в контексте расширения пути, будет соответствовать всем файлам и нулю или более каталогам и подкаталогам. Если за шаблоном следует /, совпадают только каталоги и подкаталоги.

Поскольку мы можем использовать ** чтобы найти файлы, нам просто нужно определить новое имя как включающее исходные имена каталогов и изменение . к _:

для файла в формате **/*.txt; делать 
    newName=$(sed 's|[/.]|_|g' <<<"$file" | sed 's/_txt$/.txt/')
    cp -- "$file" foo/"$newName" 
сделано

Объяснение

  • для файла в формате **/*.txt; делать: найти все файлы (и каталоги, если это важно) в текущем каталоге, имя которых заканчивается на *.текст.
  • newName=$(sed 's|[/.]|_|g' <<<"$file" | sed 's/_txt$/.txt/') : использовать сед преобразовать все / и . к _ в имени файла. Обратите внимание, что $ файл сюда также входит путь, так что это будет что-то вроде case1/0.25/case1.txt и это становится case1_0_25_case1_txt. Затем мы передаем вывод первого сед ко второму, который преобразует _текст (если найдено в конце строки) на .текст, что дает нам case1_0_25_case1.txt. Окончательный результат сохраняется в переменной $новоеИмя`.
  • cp -- "$file" foo/"$newName": теперь мы копируем файл в каталог фу/ и с новым именем. -- на самом деле здесь не требуется, но гарантирует, что подход будет работать с любым именем файла, включая те, имя которых начинается с -.

Я воссоздал структуру папок, которую вы показываете в своем вопросе, выполнил команду выше и получил:


$ дерево
.
✓ Дело 1
≈ ≈ 0,25
â â  âââ case1.txt
≈ ≈ 0,30
â â  âââ case1.txt
≈ ≈ 0,35
â â  âââ case1.txt
âââ 0,45
âââ case1.txt
âââ case2
≈ ≈ 0,25
â â  âââ case2.txt
≈ ≈ 0,30
â â  âââ case2.txt
≈ ≈ 0,35
â â  âââ case2.txt
âââ 0,45
âââ case2.txt
âââ фу
    âââ case1_0_25_case1.txt
    âââ case1_0_30_case1.txt
    âââ case1_0_35_case1.txt
    âââ case1_0_45_case1.txt
    âââ case2_0_25_case2.txt
    âââ case2_0_30_case2.txt
    âââ case2_0_35_case2.txt
    âââ case2_0_45_case2.txt

11 каталогов, 16 файлов

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.