2015-11-02 3 views
4

Предполагается, что echo $PATH дает /first/dir:/second/dir:/third/dir.

Вопрос: Как один эхо содержимое $PATH один каталог, в то время как в:

``` 
$ newcommand $PATH 
/first/dir 
/second/dir 
/third/dir 
``` 

Предпочтительно, я пытаюсь выяснить, как сделать это с помощью for цикла, что вопросы один экземпляр echo на экземпляр каталога в $PATH.

ответ

0

Вы можете использовать tr (перевести), чтобы заменить двоеточия (:) новыми символами (\n), а затем перебрать их в цикле for.

directories=$(echo $PATH | tr ":" "\n") 
for directory in $directories 
do 
    echo $directory 
done 
+0

Отсутствие причин для повторения итерации вашего вывода с новой строкой. И это не будет работать для записей пути, в которых есть пробелы (или символы глобуса). –

+0

@ EtanReisner задал вопрос именно о нем – doublesharp

+0

Достаточно честно, я бы замалчивал это предпочтение. Это все еще небезопасно для пробелов или глобусов, хотя и означает, что преобразование в пробелы или 'NUL', вероятно, будет лучше, а затем разобрать это для цикла (хотя бы 'while'). –

2

Как об этом:

echo "$PATH" | sed -e 's/:/\n/g' 

(см sed's s command, sed -e 'y/:/\n/' также будет работать, и эквивалентно tr ":" "\n" от некоторых других ответов.)

Это предпочтительнее не усложнять, если абсолютно необходимо: цикл for здесь не нужен. Есть и другие способы, чтобы выполнить команду для каждого элемента в списке, в соответствие с Unix Philosophy:

Это Unix философия: Написание программ, которые делают одну вещь и делают это хорошо. Напишите программы для совместной работы. Пишите программы для обработки текстовых потоков, потому что это универсальный интерфейс.

, такие как:

echo "$PATH" | sed -e 's/:/\n/g' | xargs -n 1 echo 

Это функционально эквивалентен для цикла перебора элементов PATH, выполнив эту последнюю echo команду для каждого элемента. -n 1 сообщает xargs, чтобы указать только 1 аргумент; без него мы получим тот же результат, что и echo "$PATH" | sed -e 'y/:/ /'.
Поскольку это использует xargs, которая встроена поддержка разделить вход и повторяет вход, если команда не задана, мы можем написать, что, как:

echo -n "$PATH" | xargs -d ':' -n 1 

-d ':' говорит xargs использовать : для разделения это ввод, а не новая строка, и -n сообщает /bin/echo, чтобы не писать новую строку, иначе мы закончим с пустой задней строкой.

+1

Представьте свои расширения переменных. '' $ PATH "' –

+0

Вопрос о том, чтобы он использовался в цикле 'for' – doublesharp

5
echo "$PATH" | tr ':' '\n' 

Необходимо сделать трюк. Это просто выведет вывод echo "$PATH" и заменит любой двоеточник разделителем новой строки.

Обратите внимание, что кавычки около $PATH предотвращают сведение нескольких последовательных пробелов на выходе $PATH, сохраняя при этом содержимое переменной.

+1

Представьте свои расширения переменных. '' $ PATH "' –

+0

Вопрос просил его использовать в цикле 'for' – doublesharp

+1

@ doublesharp Он сказал предпочтительно. Я даю решение, которое касается не только его потребностей, но и мышления о других людях, которые ищут это в Google/SO. – CydrickT

1

Моя идея - использовать echo и awk.

echo $PATH | awk 'BEGIN {FS=":"} {for (i=0; i<=NF; i++) print $i}' 

EDIT

Эта команда лучше моей прежней идее.

echo "$PATH" | awk 'BEGIN {FS=":"; OFS="\n"} {$1=$1; print $0}' 
+0

Представьте свои расширения переменных. '' $ PATH "' –

+1

Установите 'OFS =" \ n "', и awk выполнит разделение новой строки для вас. (После того, как вы его убедите, вы изменили строку с чем-то вроде '$ 1 = $ 1'.) –

1

В качестве дополнительной опции (и в случае, если вам нужны записи в массиве для других целей), вы можете сделать это с помощью пользовательских IFS и read -a:

IFS=: read -r -a patharr <<<"$PATH" 
printf %s\\n "${patharr[@]}" 

Или так как вопрос спрашивает для версии с для цикла:

for dir in "${patharr[@]}"; do 
    echo "$dir" 
done 
+1

Цикл массива + для цикла - это единственный подход, который будет работать для * всех * юридических значений« PATH »(в том числе с именами каталогов, содержащих новую строку персонажи). (Ограничение 'PATH' означает, что имя каталога, содержащее': ', хотя и законное, не может быть добавлено в' PATH'. – chepner

0

Если вы можете гарантировать, что PATH не содержит пробелы, вы можете:

for dir in ${PATH//:/ }; do 
    echo $dir 
done 

Если есть встроенные пространства, это сильно испортится.

+0

Это также не работает с оболочками. 'Р = 'А:/бен/*: В'; echo $ {P //: /} ' –

Смежные вопросы