Scripting lote de texto mangling

1

Muitas vezes me vejo tentando manipular textos triviais em arquivos bastante grandes. Parece que deveria haver uma maneira de roteirizar isso com uma ou outra das várias ferramentas de manuseio de texto do Unix, mas não consigo descobrir exatamente como fazê-lo.

Como um exemplo concreto, suponha que eu tenha algum código-fonte assim:

foo1 = undefined
foo2 = undefined
foo3 = foobar 7
foo4 = undefined

Eu quero transformá-lo para ficar assim:

foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"

Parece que deve haver alguma forma de fazer essa transformação automaticamente. Obviamente eu posso facilmente escrever um programa em uma linguagem de programação real. Mas certamente há alguma ferramenta de linha de comando que pode fazer isso. (?)

Como um exemplo mais complexo, como eu viro

foo=ABC
bar=DEF
baz=GHI
foo=123
bar=456
baz=789

em

Magic(ABC, DEF, GHI);
Magic(123, 456, 789);

Mais geralmente, qual ferramenta devo analisar para fazer esse tipo de transformação? Isso é sed ou awk ou ...?

    
por MathematicalOrchid 06.08.2015 / 21:48

3 respostas

2

Depende da situação particular. Seu primeiro exemplo pode ser resolvido usando sed ou awk . Por exemplo, usando awk :

$ awk '
/undefined/ {printf "%s = error \"%s\"\n", $1, $1; next}
{print}
' input

Que produz:

foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"

Ou usando sed :

sed '
  /undefined/ s/\([^ ]*\) =.*/ = error ""/
' input

Seu segundo exemplo provavelmente seria mais fácil de fazer com awk ou alguma linguagem de nível superior como Perl ou Python. Novamente, com awk :

awk '
{
    split($0, parts, "=")
    items[i++] = parts[2]
}
i%3 == 0 {
    printf "Magic(%s, %s, %s)\n", items[0], items[1], items[2]
    i=0
}

' input

Que produz:

Magic(ABC, DEF, GHI)
Magic(123, 456, 789)

Mais geralmente ... Não tenho certeza se é possível fornecer uma resposta geral. Isso realmente depende da tarefa específica que você está tentando realizar. Uma vez que você retirou awk você já está escrevendo um programa em uma linguagem de programação real , então você não deve evitar uma ferramenta de nível superior (como Perl ou Python ou Ruby ou qualquer outra coisa) só porque é mais capaz.

    
por 06.08.2015 / 22:33
1

sed é ótimo para manipulação de texto simples - normalmente edições de linha única, embora possa trabalhar com várias linhas (com muito esforço). No geral, sed é bastante limitado, pela falta de variáveis e cálculos aritmáticos, mas ainda assim oferece a solução mais simples em muitos casos.

awk é muito eficaz para manipulações simples e complexas de cálculos de texto e números, mas não é ideal para coisas além disso.

Para o primeiro exemplo:

sed -E 's/^([^ ]+) = undefined$/ = error ""/' file1
awk '$3=="undefined"{ $3="error \"" $1 "\"" } {print $0}' file1

Para o segundo exemplo, com base em valores de sendo all-UPPERCASE alpha ou all-NUMERIC. Também agrupa quaisquer linhas não-mágicas (para remover, basta excluir out[0] declarações):

awk -F'=' 'BEGIN{ # split regular expressions, using 'x7F' as delimiter (or any char not in the regex)  
                  n=split("^[A-Z]+$" "\x7F" "^[0-9]+$",rx,"\x7F") 
           } 
           { for( i=1;i<=n;i++ ){
                 if( $2 ~ rx[i] ){ 
                     out[i]=out[i] sprintf( (out[i] ?", " :"") "%s", $2)
                     break 
             }   } 
             if( i>n ) out[0]=out[0] $0 RS # non-matching lines 
           }
           END{ printf out[0]
                for( i=1;i<=n;i++ ){ print "Magic(" out[i] ")" }
           }' file2
    
por 07.08.2015 / 01:05
0

Eu usaria o Perl, como é uma linguagem de programação (razoavelmente "normal"), construída em torno da poderosa manipulação de texto (search, replace no estilo vi (1) com expressões regulares). Mas muitos me considerariam um herege e usariam o Python. Ambos são distribuídos com qualquer distribuição Linux e têm implementações decentes do Windows (e tenho certeza também para o Mac). O Python tem a vantagem de ser usado para construir grande parte da GUI para ferramentas de administração, por exemplo, Fedora, então deve estar instalado.

awk(1) e sed(1) são ferramentas poderosas, mas um pouco decididas ...

    
por 07.08.2015 / 14:00