1

Мои проекты разделены на три каталога: данные, сценарии и результаты. Основной конвейер вызывается из каталога в верхней части этих трех каталогов. Данные содержат ряд подкаталогов, по которым я хочу выполнить цикл, восстановить их имена и, чтобы сохранить порядок, создать новые каталоги с тем же именем в результатах. Я делаю это с помощью следующего скрипта:

for d in data/*
   do 
   newname=$(echo $d | cut -f2 -d /)
   mkdir /results/$newname
   myprogram $d/raw_data > ../results/$newname/output
   done

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

for d in (??????)
   do
   mkdir /Results/$d
   myprogram Data/$d/rawdata > results/$d/output
   done

РЕДАКТИРОВАТЬ Я только что пришел с этой идеей для первой строки, которая довольно хорошо работает со вторым фрагментом кода

for d in $(ls -d  data/* | cut -f2 -d /)

У кого-нибудь есть лучшее предложение?

1 ответ1

2

Это можно сделать с помощью удаления префикса:

for d in data/*
do
   mkdir "./results/${d#*/}"
   myprogram "$d/raw_data" > "../results/${d#*/}/output"
done

Конструкция ${d#*/} называется удалением префикса. Он удаляет все до первого / в строке $d . В качестве примера:

$ d=data/subdir1
$ echo "${d#*/}"
subdir1

Заметки

  1. Если вы не хотите разделения слов и расширения пути, все переменные оболочки должны быть в двойных кавычках.

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

  3. Альтернатива удаления префикса , как показано выше , является исполняемой dirname

Документация

От man bash:

$ {Параметр # слово}
$ {Параметр ## слово}

Удалить соответствующий префикс шаблона. Слово раскрывается для создания шаблона, как в раскрытии пути. Если шаблон соответствует началу значения параметра, то результатом раскрытия является расширенное значение параметра с удалением самого короткого шаблона сопоставления (случай # ) или самого длинного шаблона сопоставления (случай ## ). Если параметр равен @ или *, операция удаления шаблона применяется по очереди к каждому позиционному параметру, и расширение является результирующим списком. Если параметр является переменной массива, подписанной @ или *, операция удаления шаблона применяется по очереди к каждому члену массива, и расширение является результирующим списком.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .