Identificando e movendo campos em uma linha

0

Eu quero identificar um campo em uma linha contendo uma string e, em seguida, movê-lo para uma posição diferente. Uma linha ficaria assim (desculpe, eu não consigo digitar as abas aqui)

string1 / string2 / blablaABCbla / string3

A idéia é localizar o campo contendo ABC e mover esse campo para o início ou fim da linha. Como eu faria isso no bash, do stdout?

[editar]

Estou tentando trabalhar isso em uma sequência de canais - eu estava esperando por um comando inteligente que eu não soubesse, ou algo realmente feio.

    
por operalala 02.02.2014 / 21:36

2 respostas

2

Eu uso o AWK (um comando UNIX / Linux padrão que existe até mesmo uma implementação do Busybox) para um problema como esse, por exemplo

#!/bin/sh

awk -F'\t' 'BEGIN{srand()} {
    X=$0
    for(a=1;a<=NF;a++) {
        if($a ~ /ABC/) {
            if(rand() < .5) {
                X = $a " " $0 # Concat strings
            } else {
                X = $0 " " $a
            }
       }
   }
print X
}'

Como um aparte, eu não acho que a solução AWK seja mais complicada do que uma solução em Python:

#!/usr/bin/env python

import random
import re
import sys

for line in sys.stdin:
        fields = re.split('\t',line[:-1])
        out = line[:-1]
        for field in fields:
                if re.search('ABC',field):
                        if random.randint(0,1) == 1:
                                out = field + " " + line[:-1]
                        else:
                                out = line[:-1] + " " + field
        print out
    
por 02.02.2014 / 22:16
2

Manipular uma string da maneira que você pediu é um pouco de trabalho usando apenas o Bash. É factível, mas acho que usar o Perl é muito mais fácil. Este one-liner Perl também fará o que você quer:

$ perl -a -F'\s*/\s*' -lne '
   printf "%s / ", grep( /ABC/, @F ); 
   printf "%s / %s / %s\n",  grep( !/ABC/, @F ); 
' file
blablaABCbla / string1 / string2 / string3

Esta solução assume uma entrada formatada com 4 colunas e que o ABC estará presente. Você pode inverter a ordem das linhas printf...grep... para obter o ABC no início (como mostrado) ou no final da linha. Você precisará fazer algumas modificações assim:

$ perl -a -F'\s*/\s*' -lne '
   printf "%s / %s / %s / ",  grep( !/ABC/, @F ); 
   printf "%s\n", grep( /ABC/, @F );
' file 
string1 / string2 / string3 / blablaABCbla
    
por 02.02.2014 / 23:31

Tags