У меня есть команда cmd
это берет строку в качестве параметра, и возвратите другую строку.
Я должен подать заявку, эта команда к одному определенному столбцу файла, форматированного в 5x7 таблица (скажите что 3-й столбец), так, чтобы вместо наличия
string11 string12 string13 string14 string15 string16 string17
string21 string22 string23 string24 string25 string26 string27
string31 string32 string33 string34 string35 string36 string37
string41 string42 string43 string44 string45 string46 string47
string51 string52 string53 string54 string55 string56 string57
Я имею
string11 string12 $(cmd string13) string14 string15 string16 string17
string21 string22 $(cmd string23) string24 string25 string26 string27
string31 string32 $(cmd string33) string34 string35 string36 string37
string41 string42 $(cmd string43) string44 string45 string46 string47
string51 string52 $(cmd string53) string54 string55 string56 string57
где $(cmd string<i><j>)
представьте строковый вывод, следующий из применения cmd
кому: string<i><j>
Как применить пользовательскую команду cmd
к произвольному номеру столбца файла, отформатированного как таблица?
PS: Я предпочел бы использовать awk
вместо sed
.
С помощью gawk
(и, вероятно, с nawk
- но, насколько я могу судить, с mawk
), вы должны быть в состоянии сделать это, используя "command" | getline variable
форму getline
.
Например, с помощью следующего скрипта в качестве теста cmd
, который принимает один строковый параметр и выводит его версию в верхнем регистре
#!/bin/sh
printf '%s' "$1" | sed 's/.*/\U&/'
, а затем вводит образец в виде file
$ gawk '{"./cmd "$3 | getline $3}1' file
string11 string12 STRING13 string14 string15 string16 string17
string21 string22 STRING23 string24 string25 string26 string27
string31 string32 STRING33 string34 string35 string36 string37
string41 string42 STRING43 string44 string45 string46 string47
string51 string52 STRING53 string54 string55 string56 string57
Существует не очень хорошо известная функция sed
это позволяет Вам выполнять команду. Это для GNU sed и названо с /e
:
$ sed 's/1/echo 555/e' <<< "123"
55523
В нашем случае давайте поймаем блок и обработаем его через данный cmd
:
Во-первых, путем ловли групп правильно:
$ sed -r 's/^((\w+\W+){2})\w+(.*)/printf "%s%s%s" "\1" "\2" "\3"/e' file
string11 string12 string12 string14 string15 string16 string17
string21 string22 string22 string24 string25 string26 string27
string31 string32 string32 string34 string35 string36 string37
string41 string42 string42 string44 string45 string46 string47
string51 string52 string52 string54 string55 string56 string57
Это в основном получает целую строку и печатает ее назад через printf
и использование полученных групп как аргументы. Вы видите теперь, что это немного глупо, потому что это просто печатает назад.
Так как Вы можете для выполнения cmd
против данной строки необходимо использовать:
sed -r 's/^((\w+\W+){2})\w+(.*)/printf "%s%s%s" "\1" "$(cmd "\2")" "\3"/e' file
Сказать cmd
awk 'BEGIN {print 1}'
, затем мы сказали бы:
$ sed -r 's/^((\w+\W+){2})\w+(.*)/printf "%s%s%s" "\1" "$(awk "BEGIN{print 1}")" "\3"/e' file
string11 string12 1 string14 string15 string16 string17
string21 string22 1 string24 string25 string26 string27
string31 string32 1 string34 string35 string36 string37
string41 string42 1 string44 string45 string46 string47
string51 string52 1 string54 string55 string56 string57
Как Вы видите, идея здесь
Все это основано на замене Sed выводом команды удара с помощью группы получения в качестве аргумента, который я создал на основе того, Как изменить формат даты в sed?.