Como aplicar um comando em todos os campos de uma coluna específica?

4

Eu tenho um comando cmd que usa uma string como parâmetro e retorna outra string.

Eu preciso aplicar este comando a uma coluna específica de um arquivo formatado em uma tabela 5x7 (digamos, a terceira coluna), para que, em vez de ter

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

Eu tenho

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

em que $(cmd string<i><j>) representa a saída de sequência resultante da aplicação de cmd a string<i><j>

Como aplicar um comando personalizado cmd a um número de coluna arbitrário de um arquivo formatado como uma tabela?

PS: Eu preferiria usar awk em vez de sed .

    
por user625589 30.11.2016 / 23:01

2 respostas

3

Com gawk (e provavelmente com nawk - mas não, até onde eu sei, com mawk ) você poderá fazer isso usando a forma "command" | getline variable de getline .

Por exemplo, com o script a seguir como um teste cmd que usa um único parâmetro de string e gera sua versão em maiúsculas

#!/bin/sh

printf '%s' "" | sed 's/.*/\U&/'

depois, com sua entrada de amostra como file

$ gawk '{"./cmd " | getline }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
    
por steeldriver 01.12.2016 / 01:28
0

Existe um recurso não muito conhecido de sed que permite executar um comando. Isto é para o GNU sed e é chamado com /e :

$ sed 's/1/echo 555/e' <<< "123"
55523

No nosso caso, vamos pegar o bloco e processá-lo através do cmd :

Primeiramente, pegando os grupos corretamente:

$ sed -r 's/^((\w+\W+){2})\w+(.*)/printf "%s%s%s" "" "" ""/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

Isso basicamente captura a linha inteira e imprime de volta através de printf e usando os grupos capturados como argumentos. Você vê agora é um pouco bobo, porque apenas imprime de volta.

Como você pode executar cmd na string fornecida, use:

sed -r 's/^((\w+\W+){2})\w+(.*)/printf "%s%s%s" "" "$(cmd "")" ""/e' file

Digamos que cmd é awk 'BEGIN {print 1}' , então diríamos:

$ sed -r 's/^((\w+\W+){2})\w+(.*)/printf "%s%s%s" "" "$(awk "BEGIN{print 1}")" ""/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

Como você vê, a ideia aqui é

Tudo isso é baseado em Sed substitui a saída de um comando bash usando o grupo de captura como argumento que eu criei com base no Como alterar o formato da data no sed? .

    
por fedorqui 01.12.2016 / 14:17