1

У меня есть папка, в которой есть несколько папок. Я получаю список всех папок, используя следующую команду:

ls -1a -d */ 

Это возвращает что-то вроде этого:

folder01/
folder02/
folder03/
...

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

./process_folder.sh sample/folder01/
./process_folder.sh sample/folder02/    
./process_folder.sh sample/folder03/
./process_folder.sh sample/folder04/

Как вы можете видеть, я запускаю ./process_folder.sh поверх результатов команды ls, и в нем есть небольшое изменение - я добавил sample/ перед именем каждой папки.

Итак, вопрос в том, как я могу сделать все это с помощью команды в моей оболочке? (Как я помню, я мог использовать | или > но я не мог вспомнить детали).

3 ответа3

4

Не анализируйте программно вывод ls .

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

$ mkdir -p newdir/folder0{1,2,3}
$ cd newdir
$ ls -1ad */
folder01//
folder02//
folder03//
$

Видишь эти двойные косые черты? Это потому, что я связал ls с ls --color=auto -F .

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

$ mkdir -p newdir/folder0{1,2,3}
$ cd newdir
$ find . -mindepth 1 -maxdepth 1 -type d -printf './process_folder.sh sample/"%P"/\n'
./process_folder.sh sample/"folder03"/
./process_folder.sh sample/"folder01"/
./process_folder.sh sample/"folder02"/
$

-mindepth 1 -maxdepth 1 ограничивает поиск только заданные исходные каталоги . в данном случае) и исключает сам начальный каталог. -type d ограничивает соответствие только каталогами. -printf - это действие, которое может выполнить find, которое печатает метаданные о записи каталога, найденной в заданном формате; %P в строке формата заменяется именем найденной записи минус начальный каталог. Смотрите man 1 find для более подробной информации.

Если вы хотите создать скрипт для запуска позже, перенаправьте вывод find в файл:

$ find . -mindepth 1 -maxdepth 1 -type d -printf './process_folder.sh sample/"%P"/\n' > process_folders.sh

Если вам нужна одна команда, которая выполняет команды немедленно, вместо этого перенаправьте вывод команды find в оболочку:

$ find . -mindepth 1 -maxdepth 1 -type d -printf './process_folder.sh sample/"%P"/\n' | bash

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

2

Вы хотите цикл:

for d in $(ls -1a -d */); do
  ./process_folder.sh "sample/$d"
done
2

Вы можете попробовать следующую команду:

find . -type d -mindepth 1 -maxdepth 1 -exec bash -c ' /path/to/process_folder.sh "sample/${0##*/}" ' {} \;

Это находит каталоги в вопросах и запускает process_folder для каждого из них одновременно: одну команду вместо двух. Кроме того, он невосприимчив к проблемам разбора.

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