2015-04-28 3 views
-1

Ive получил файл под названием school.test и это выглядит следующим образом:Назначение переменных в цикле

David  maths 
Sam   maths 
Sam   english 
Simon  french 
Simon  english 

Я хочу, чтобы написать цикл, который читает этот текстовый файл до построчно и назначить значения, он считывает эту строку для разных переменных и запускает ее через команду. Проблема в том, что я не знаю, как установить первое значение как переменную, а второе значение - как другую переменную.

Например, для первой линии для цикла читает это будет выглядеть примерно так:

for line in `cat/home/school.test` 
do 
positionClient -name [variable=David] -class [variable=math] 
done 

и так далее, и так далее. Как мне это сделать?

+0

http://stackoverflow.com/questions/9293887/in-bash-how-do-i-convert-a-space-delimited-string-in-the-array может помочь – Doon

+1

Я понятия не имею, какое название имеет отношение к вопросу. –

+0

http://mywiki.wooledge.org/BashFAQ/001 –

ответ

3
$ while read name subject 
> do 
> echo "Name: $name, Subject: $subject" 
> done <<< 'David  maths 
> Sam   maths 
> Sam   english 
> Simon  french 
> Simon  english' 
Name: David, Subject: maths 
Name: Sam, Subject: maths 
Name: Sam, Subject: english 
Name: Simon, Subject: french 
Name: Simon, Subject: english 

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

+0

, поэтому я пытаюсь использовать этот метод, но его не работает для меня: 'в то время как прочитанное название субъекта do echo" symbol: $ symbol "; echo "инвентарь: $ inventory" сделано << nrs90

+0

'<<<' для торжества. Перенаправление ввода файлов использует '<' как всегда. –

+0

, и вам нужно прочитать «awk», предпочтительный (например, не perl) способ иметь дело с (по существу) таблицами в unix. _ then_, когда вам удобно с awk, вы должны скачать RDB, например. поиск/rdb - управление базами данных unix realational, schaefer, manis и jorgenson. Это изменит вашу жизнь. –

3

Вы можете использовать встроенный read для этого:

cat /home/school.test | while read name class ; do 
    positionClient -name "$name" -class "$class" 
done 

Я предпочитаю трубу cat так, используя перенаправление ввода/вывода с while цикла выглядит немного странно ("что done делать с этим файлом? ? "):

while read name class ; do 
    positionClient -name "$name" -class "$class" 
done < /home/school.test 

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

+2

Использование переадресации не выглядит нечетным и позволяет избежать работы в подоболочке. –

+0

Чтобы добавить комментарий @WilliamPursells, он также позволяет использовать переменные, установленные в цикле, снаружи (так как это не подоболочка). –

+0

@WilliamPursell: Я согласен с проблемой подоболочки, но что делает 'done' с файлом? Кроме того, наличие ввода в конце кодового блока является странным. И когда тело петли большое, это легко упустить. –

-1

Существуют различные способы получения значений в разные переменные. Один из способов уже упоминается в других ответах, то есть с использованием встроенного в read.

Позвольте мне объяснить другой подход. Вот один подход с использованием awk. Это может быть не самое оптимальное (из-за подоболочки), но оно работает.

for line in `cat school.test` 
do 
    name=`echo $line | awk '{print $1}'` 
    class=`echo $line | awk '{print $2}'` 
    positionClient -name "$name" -class "$class" 
done 
+0

вопрос использование «оптимальный». «оптимальный» должен иметь меньше общего с PERFOMANCE, а больше - с SIMPLE, чтобы ЧИТАТЬ ЧЕЛОВЕКОМ, а не то, что у вас нет, и вы определили SUBoptimality, не переделывая один awk, если вы настаиваете, можете сделать работайте, см. использование «SET -» ниже. –

+0

@MartyMcGowan: Ваше решение хорошее. И я понимаю, как работает 'set''. Но, пожалуйста, помогите мне понять, как лучше использовать метод' set' читабельность, чем метод 'awk'? Также я упомянул, что это был ** один подход **, а не только ** **. – meetrp

0

, если вы настаиваете на использовании цикла оболочки, а затем:

for line in `cat school.test` 
do 
    set -- $line # $1 is NAME, and $2 is CLASS. 
    # NB since awk didn't distinguish separator, NO NEED to quote $1, $2 
    positionClient -name $1 -class $2 
done 

OR, вот один вкладыш:

awk 'BEGIN { fmt="positionClient -name %s -class %s\n"; }; { print fmt, $1, $2 }' school.test | sh -x 
Смежные вопросы