Как применить команду на все поля одного определенного столбца?

У меня есть команда 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.

4
задан 1 December 2016 в 04:32

2 ответа

С помощью 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
3
ответ дан 1 December 2019 в 10:01

Существует не очень хорошо известная функция 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?.

0
ответ дан 1 December 2019 в 10:01

Другие вопросы по тегам:

Похожие вопросы: