2016-03-17 2 views
0

Уверен, что на это был дан ответ раньше, но я не могу найти решение.Bash variable in for loop

for i in `ls | grep ^t`; do echo $i; done 

Это дает мне ожидаемые результаты (файлы и каталоги, начинающиеся с t). Если я хочу использовать переменную оболочки в цикле for (с каналом), как это сделать? Это было мое начало, но это не сработало.

z="ls | grep ^t" 
for i in `$z` ; do echo $i; done 

EDIT: Я согласен, этот пример не мудро выбрал, но то, что я в принципе нужно IShow использовать переменную (здесь $z) в течение цикла (for i in $z), который имеет, по меньшей мере, одну трубу.

Я пытаюсь более четко изложить свой вопрос: как мне нужно определить мою переменную (если я хочу, чтобы цикл по выходу команды с одним или несколькими каналами) и как вызов цикла for?

+0

вы должны написать 'Z = \' Ls | grep^t \ '' –

+1

@PatrickTrentin Это синтаксически корректно, но вы не должны его использовать. – chepner

+0

@chepner достаточно честный; eta: не-ум, я посмотрел это сам. (: –

ответ

4

Переберите все файлы, начинающиеся с t, вы должны использовать glob расширение вместо разбора ls вывод:

$ ls t* 
tf tfile 
$ ls 
abcd tf tfile 
$ for i in t*; do echo "$i"; done 
tf 
tfile 
$ 

Ваш подход сломается в ряде случаев, простейшего существа, когда имена файлов содержат пробелы. Здесь нет необходимости использовать внешний инструмент; t * распространяется на все файлы, начиная с t.

Что касается вашего вопроса, вы используете ls | grep ^t

И еще одна хорошая практика заключается в использовании подоболочку вместо обратные кавычки, которые являются более удобным для чтения и может быть вложен, используйте: $(ls | grep ^t)

+1

Я только прочитал первую часть вашего ответа, поэтому я разместил свой собственный. Ваш совет использовать 't *' - лучшая идея - вы должны перенести это в начало своего ответа, тогда я удалю свой. –

+0

@TomFenech Нет проблем :) .. отредактировал его – ritesht93

0

Вы не использовать переменная для этого. Вы не ставите команды в строки. См. Bash FAQ 050 для обсуждения причин.

Вы не должны использовать цикл for, чтобы читать данные по очереди в любом случае. См. Bash FAR 001, чтобы найти лучший способ сделать это.

В частности (хотя на самом деле читать эту страницу):

while IFS= read -r line; do 
    printf '%s\n' "$line" 
done < <(some command)