Я новичок в ubuntu, а также в мире программирования, и Я действительно не знаю, как это сделать!
У меня есть папка с множеством файлов, названных следующим образом:
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
Скажем, xxx_S_xxx - это основное имя, а остальная часть имени файла дает вторичную информацию (назовем это вторичным именем).
Я хотел бы найти конкретное имя во вторичном имени и создать папку с этим именем (например, mpc, dtd или flf), затем создать вложенные папки, названные в качестве основного имени каждого файла, и в эти папки поместить соответствующие файлы. Возможно, изображение лучше объяснит то, что я пытаюсь сказать.
Так, например, выходные данные для имен, которые я дал вам выше, будут выглядеть так:
Можно ли это сделать с терминала? Я был бы признателен твоя помощь.
Моя ОС - Ubuntu 20.04 LTS
Я не совсем уверен, как это сделать только в терминале, чтобы его не было слишком трудно читать, но я думаю, что вы могли бы получить результат, который ищете, или по крайней мере, начните с чего-то вроде этих строк:
Изменить: обновлено информацией из комментария. Также поменяны местами вторичный и первичный, так как они были наоборот.
Edit2: понял, что, хотя вторичное имя больше не зависит от размещения, основное имя зависит от размещения вторичного.
#!/bin/bash
input_directory="/path/to/your/data"
output_directory="/path/to/your/output"
cd "$input_directory"
for file in *; do
if [ ! -f "$file" ]; then
continue;
fi
# place your secondary names inside "(mpc|flf|dtd)" seperated by '|'
secondary=$(echo "$file" | grep -o -E "(mpc|flf|dtd)");
princple=$(echo "$file" | grep -o -E "([0-9]+_S_[0-9]+)");
# skip over and alert that a secondary match was not found for a file
if [ "$secondary" == "" ]; then
echo "No secondary match found!! Skipping $file";
continue;
fi
destination="${output_directory}/$secondary/$princple"
# create the directories if they don't exist
if [ ! -d "$destination" ]; then
mkdir -p "$destination";
fi
# uncomment to move the files to the new directories if the test output
# from echo is correct
#mv "$file" "$destination"
# test to print result of moving the files
from=$(readlink -f "$file")
echo "$from -> $destination/$file"
done
grep -o -E "(mpc | flf | dtd)"
ищет в имени файла одно из вторичных ключевых слов имени, например (mpc, dtd или flf) и сохраняет это слово во вторичной переменной.
grep -o -E "([0-9] + _ S_ [0-9] +)
Та же идея, поиск шаблона xxx_S_xxx.
Его можно запустить как: bash script.sh
Переменные input_directory
и output_directory
должны быть заполнены правильными путями. Кроме того, поля "(mpc | flf | dtd)" в grep можно заполнить выписку с другими вторичными лицами.
В случаях, когда структура целевого каталога не существует, вы можете разрезать путь на части и напоминать их в желаемом порядке.
#!/bin/bash
while IFS=_ read -r a b c d e; do
mkdir -p target/$d/${a##*/}_${b}_${c}; mv -t $_ ${a}_${b}_${c}_${d}_$e
done < <(printf %s\\n files/*)
Или регулярное выражение , где массив BASH_REMATCH
записывает совпавшие части. Первый массив , член содержит часть, которая соответствует всему регулярному выражению. Подстроки, соответствующие подвыражениям в скобках, назначаются следующим членам.
#!/bin/bash
for i in files/*; do
if [[ $i =~ ^files/([0-9]+_S_[0-9]+)_(mpc|dtd|flf) ]]; then
mkdir -p target/${BASH_REMATCH[2]}/${BASH_REMATCH[1]}; mv -t $_ $i
fi
done
Вы также можете разделить процесс на два этапа, где вы начинаете с создания структуры каталогов сначала awk
в сочетании с xargs
оптимизирует использование mkdir
а затем используйте, например, mmv
для переименования.
#!/bin/bash
builtin cd files
printf %s\\0 * | \
awk -F _ ' \
BEGIN{ RS = ORS = "\0" } { printf("../target/%s/%s_%s_%s\0", $4, $1, $2, $3) } \
' | xargs -0 mkdir -p
# Remember we have change our working directory.
mmv -m '*_S_*_*_*' '../target/#3/#1_S_#2/#1_S_#2_#3_#4'