Как переместить файлы в папки с похожими именами в Unix? - PullRequest
0 голосов
/ 21 января 2019

Извините, если этот вопрос задавался ранее, я просто не знал, как его обозначить как поисковый запрос.

У меня есть набор папок, которые выглядят так:

Brain - Amygdala/                 Brain - Spinal cord (cervical c-1)/  Skin - Sun Exposed (Lower leg)/
Brain - Caudate (basal ganglia)/  Lung/                                Whole Blood/

У меня также есть набор файлов, которые выглядят так:

Brain_Amygdala.v7.covariates_output.txt                  Skin_Not_Sun_Exposed_Suprapubic.v7.covariates_output.txt
Brain_Caudate_basal_ganglia.v7.covariates_output.txt     Skin_Sun_Exposed_Lower_leg.v7.covariates_output.txt
Brain_Spinal_cord_cervical_c-1.v7.covariates_output.txt  Whole_Blood.v7.covariates_output.txt

Как видите, файлы не полностью совпадают с каталогами в своих именах. Например, Brain_Amygdala.v7.covariates_output.txt не полностью идентичен Brain - Amygdala/. Даже если бы мы вырезали имя ткани из файла ковариат, Brain_Amygdala отформатирован иначе, чем соответствующая папка.

То же самое с Whole Blood/. Он отличается от Whole_Blood.v7.covariates_output.txt, даже если вы должны были изолировать название ткани из файла ковариат Whole_Blood.

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

, например

Brain_Amygdala.v7.covariates_output.txt -> Brain*Amygdala [mv] -> Brain*Amygdala/

a) Я не уверен, как изолировать первые слова имени файла, ведущего к первому . в имени файла

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

Однако, Я полностью открыт для других способов сделать что-то подобное.

1 Ответ

0 голосов
/ 21 января 2019

Не полный ответ, но он должен решить некоторые из ваших проблем:

a) для выделения первого слова строки, приводящего к первому .: используйте Расширения параметров

string=Brain_Amygdala.v7.covariates_output.txt
until_dot=${string%%.*}
echo "$until_dot"

выведет Brain_Amygdala (который мы сохранили в переменной until_dot).

b) Возможно, вы захотите использовать расширение параметра ${parameter/pattern/string}:

# Replace all non-alphabetic characters by the glob *
glob_pattern=${until_dot//[^[:alpha:]]/*}
echo "$glob_pattern"

выведет (с теми же переменными, что и выше) Brain*Amygdala

c) Чтобы использовать все это: вероятно, сначала неплохо определить возможные цели и выполнить некоторые основныепроверяет:

# Use nullglob to have non matching glob expand to nothing
shopt -s nullglob
# DO NOT USE QUOTES IN THE FOLLOWING EXPANSION:
# the variable is actually a glob!
# Could also do dirs=( $glob_pattern*/ ) to check if directory
dirs=( $glob_pattern/ )

# Now check how many matches there are:
if ((${#dirs[@]} == 0)); then
    echo >&2 "No matches for $glob_pattern"
elif ((${#dirs[@]} > 1)); then
    echo >&2 "More than one matches for $glob_pattern: ${dirs[@]}"
else
    echo "All good!"
    # Remove the echo to actually perform the move
    echo mv "$string" "${dirs[0]}"
fi

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

...