Передайте определенное поле входного потока в команду и вставьте обратно результаты - PullRequest
0 голосов
/ 28 июля 2011

Скажем, у меня есть входной поток, состоящий из строк, разделенных на определенное количество полей.Я хотел бы вырезать различные поля, передать определенное поле (или поля) в программу (которая, как предполагается, возвращает одну строку для каждой входной строки), оставить другие поля как есть и вставить результаты обратно вместе.Я, вероятно, могу представить себе запутанные решения, но должен быть чистый и естественный способ сделать это.

В качестве конкретного примера, скажем, у меня есть программа, производящая строки вида:

$ inputprog
<a> hello world!
<b> hi everyone!
<a> hi!

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

$ inputprog | program -d' ' -f2- "tr a-z A-Z"
<a> HELLO WORLD!
<b> HI EVERYONE!
<a> HI!

Я ищу достаточно чистый способ приблизиться к program.(Меня не интересуют решения, характерные для этого примера.)

Заранее благодарен за помощь!

1 Ответ

1 голос
/ 28 июля 2011

awk можете делать то, что вы хотите.Например:

$ echo "field1 field2" | awk '{$2 = toupper($2); print;}'
field1 FIELD2

Подходит довольно близко к тому, что вы хотите сделать.$2 = toupper($2); изменяет второе поле, а print печатает всю (измененную) строку.

Однако у вас возникла проблема с определением «поля».В приведенном выше примере поля разделены пробелами (вы можете изменить разделитель полей на произвольное регулярное выражение следующим образом: -F'<[a-zA-Z]+>' - это будет рассматриваться как разделитель полей).Но в вашем примере вы, похоже, видите <a> как одно поле и hello world! как другое.Любая программа может прийти к вашему желаемому поведению, только угадав таким образом.Почему бы world! не считаться третьим полем?Таким образом, если вы можете получить ввод с четкой политикой разделения полей, awk - это именно то, что вам нужно.

Проверьте страницы типа http://people.cs.uu.nl/piet/docs/nawk/nawk_92.html (функции строки awk) и http://www.pement.org/awk/awk1line.txt (awk 1 liners) для получения дополнительной информации.

Кстати, ваш приведенный выше конкретный пример можно было бы также выполнить, зациклив все поля, кроме первого (NF == Количество полей):

$ echo "<a> hello world!
<b> hi everyone!
<a> hi" |  
awk '{for(i=2;i<=NF;++i) { $i=toupper($i); }; print;}'
<a> HELLO WORLD!
<b> HI EVERYONE!
<a> HI

Даже если вы не заинтересованы в решении этого примера.; -)

PS: sed также должен уметь выполнять эту работу (http://en.wikipedia.org/wiki/Sed)

...