Рейтинг:0

How to sort files into directories and subdirectories by name?

флаг id

I'm new to ubuntu and also to the programming world, and I don't really know how to do this!

I have a folder with lots of files named as follows:

000_S_001_mpc_asd.json
000_S_001_mpc_asd.nii
000_S_001_mpc_asd_aa.nii
011_S_001_mpc_asd.json
011_S_001_mpc_asd.nii
011_S_001_mpc_asd_aa.nii
000_S_002_mpc_asd.json
000_S_002_mpc_asd.nii
000_S_002_mpc_asd_aa.nii
000_S_001_dtd_rty.bval
000_S_001_dtd_rty.bvec
000_S_001_dtd_rty.nii
000_S_001_dtd_rty.json
011_S_001_dtd_rty.bval
011_S_001_dtd_rty.bvec
011_S_001_dtd_rty.nii
011_S_001_dtd_rty.json
000_S_002_dtd_rty.bval
000_S_002_dtd_rty.bvec
000_S_002_dtd_rty.nii
000_S_002_dtd_rty.json
011_S_001_flf_lkj.json
011_S_001_flf_lkj.nii
011_S_001_flf_lkj_aa.nii
000_S_001_flf_lkj.json
000_S_001_flf_lkj.nii
000_S_001_flf_lkj_aa.nii
000_S_002_flf_lkj.nii
000_S_002_flf_lkj_aa.nii

Let's say xxx_S_xxx is the principal name, and the rest of the file's name gives secondary information (let's call it a secondary name).

I would like to find a specific name into the secondary name and make a folder with this name (for example mpc, dtd or flf), then make subfolders named as the principal name of each file, and into those folders put the respective files. Probably an image will explain better what I'm trying to say.

So for example, the output for the names I gave you above would look like this:

Desired output:

Is this possible to do from the terminal? I would appreciate your help.

My OS is Ubuntu 20.04 LTS

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

В случаях, когда целевая структура каталогов не существует, вы можете дорожка на части и напоминать их в нужном порядке.

#!/бин/баш

в то время как IFS=_ read -r a b c d e; делать
    mkdir -p target/$d/${a##*/}_${b}_${c}; mv -t $_ ${a}_${b}_${c}_${d}_$e
сделано < <(printf %s\n файлов/*)

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

#!/бин/баш

для i в файлах/*; делать
    if [[ $i =~ ^files/([0-9]+_S_[0-9]+)_(mpc|dtd|flf) ]]; тогда
        mkdir -p target/${BASH_REMATCH[2]}/${BASH_REMATCH[1]}; мв -т $_ $я
    фи
сделано

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

#!/бин/баш

встроенные cd-файлы

printf %s\0 * | \
авк -F _ '\
    BEGIN{ RS = ORS = "\0" } { printf("../target/%s/%s_%s_%s\0", $4, $1, $2, $3) } \
' | xargs -0 mkdir -p

# Помните, что мы изменили наш рабочий каталог.
mmv -m '*_S_*_*_*' '../цель/#3/#1_S_#2/#1_S_#2_#3_#4'
Рейтинг:0
флаг cn

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

Изменить: обновлено информацией из комментария. Также поменял местами вторичный и первичный, так как они были задом наперед.

Edit2: понял, что, хотя вторичное имя больше не зависело от размещения, основное имя зависело от вторичного размещения.

#!/бин/баш

input_directory="/путь/к/вашим/данным"
output_directory="/path/to/your/output"

компакт-диск "$ input_directory"
для файла в *; делать

    если [ ! -f "$файл" ]; тогда
        Продолжить;
    фи

    # поместите ваши вторичные имена внутри "(mpc|flf|dtd)", разделенные символом '|'
    вторичный=$(echo "$file" | grep -o -E "(mpc|flf|dtd)");
    princple=$(echo "$file" | grep -o -E "([0-9]+_S_[0-9]+)");
    
    # пропустить и предупредить, что вторичное совпадение для файла не найдено
    если [ "$вторичный" == "" ]; тогда
        echo "Вторичное совпадение не найдено!! Пропущен файл $file";
        Продолжить;
    фи

    назначение = "${output_directory}/$вторичный/$принцип"

    # создаем каталоги, если они не существуют
    если [ ! -d "$ место назначения" ]; тогда
        mkdir -p "$ место назначения";
    фи

    # раскомментируйте, чтобы переместить файлы в новые каталоги, если тестовый вывод
    # из эха правильно
    #mv "$file" "$destination"

    # тест для вывода результата перемещения файлов
    from=$(readlink -f "$file")
    echo "$from -> $destination/$file"
сделано

grep -o -E "(mpc|flf|dtd)" ищет в имени файла одно из ключевых слов вторичного имени, например. (mpc, dtd или ffl) и сохраняет это слово во вторичной переменной.

grep -o -E "([0-9]+_S_[0-9]+) Та же идея, если искать шаблон xxx_S_xxx.

Его можно запустить как: bash-скрипт.sh

input_directory и выходной каталог переменная должна быть заполнена правильными путями. Кроме того, поля "(mpc|flf|dtd)" в операторе grep могут быть заполнены другими вторичными параметрами.

Al_Mt avatar
флаг id
У меня ничего не получается, наверное, я что-то не так делаю. Я сохранил этот код как файл .sh и запустил его из терминала ./code.sh, я ошибаюсь?
wizardpurple avatar
флаг cn
@Al_Mt Я добавил пример команды запуска. Он не будет создавать каталоги или перемещать/копировать файлы. Он просто напечатает своего рода результат теста. Я не был уверен, где вы хотите, чтобы он выводился, если вы хотите, чтобы файлы были перемещены или скопированы и т. д.
Al_Mt avatar
флаг id
Спасибо @wizardpurple. Ну, я действительно ничего не знаю о bash или оболочке, поэтому я просто попытался запустить ваш код. Я хотел бы переместить файлы в новые соответствующие каталоги. Я думаю, что это довольно точно, единственное, что иногда элемент вторичного имени, который я хочу получить, находится не на 4-й позиции, но он может варьироваться, поэтому я бы предпочел получить конкретные слова, которые я хочу (своего рода find mpc, dtd или fff) вместо позиции. Не могли бы вы помочь мне с этим?
wizardpurple avatar
флаг cn
@Al_Mt вторичный больше не должен полагаться на размещение. Он должен печатать только тест для проверки правильности, пока строка с ```mv``` не будет раскомментирована.
Al_Mt avatar
флаг id
это очень помогает!! Спасибо огромное!

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

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