filtrando dados com base no delimitador no shell

0

Eu tenho um arquivo com dados da seguinte forma:

"google1|yoo|dummy|yes|wow|/" + VARIABLE + "/"
"google2|hub|lab|dummy|yes|/" + VARIABLE + "/"
"google3|short|lab|yoo|/" + VARIABLE + "/"
"google4|hello|good-guy|bad-girl|lol|dummy|/" + VARIABLE + "/"
"google5|good-guy|a4-123|yoo|/" + VARIABLE + "/"
"google6|bad-girl|b4-124|hub|/" + VARIABLE + "/"

Agora, quero obter uma lista de strings entre o delimitador "|" (cano).

A saída deve ser como

yoo
dummy
yes
wow
hub
hello
good-guy
bad-girl
a4-123
b4-124
dummy
lol
short
lab

Basicamente, eu quero ter valores exclusivos da lista de strings após o filtro delimitador. Eu tentei usar o awk como

awk -F"|" '{gsub(/\).*/,"",$2);print $2}' file

Mas recebo dados errados.

    
por Kasino 30.09.2016 / 15:15

4 respostas

3

Se você tem grep com pcre opção:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | sort -u
a4-123
b4-124
bad-girl
dummy
good-guy
hello
hub
lab
lol
short
wow
yes
yoo
  • -o imprime apenas padrão de correspondência
  • -P usa o pcre regex
  • \|\K lookbehind positivo para ver se | está lá antes de nossa sequência ser extraída
    • semelhantemente, (?=\|) lookahead positivo para ver se há | depois que nossa sequência a ser extraída
  • [^|]+ string a ser extraída - basta negar | e obter um ou mais desses caracteres
  • sort -u para obter valor exclusivo

Se você deseja preservar a ordem na qual essas sequências são encontradas:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | awk '!seen[$0]++'
yoo
dummy
yes
wow
hub
lab
short
hello
good-guy
bad-girl
lol
a4-123
b4-124
    
por 30.09.2016 / 15:38
3

e o seguinte?

cut file -d'|' -f2,3,4 | tr '|' '\n'

O comando acima imprimirá o número fixo de colunas (3). Se você quiser imprimir um número variável de colunas, até a primeira ocorrência de / , você pode usar algo como:

cut -d'/' -f1 file | cut  -d'|' -f2- | tr '|' '\n'
    
por 30.09.2016 / 15:24
2

Se você não se importa com o pedido, pode usar um hash perl para garantir a exclusividade, por exemplo,

$ perl -lne '$h{$_}++ for /(?<=\|).*?(?=\|)/g; END{print for keys %h}' file
short
b4-124
lol
yes
bad-girl
lab
yoo
good-guy
hub
dummy
hello
a4-123
wow

Veja a criação de um hash com correspondências de regex no perl

    
por 30.09.2016 / 15:57
0

Sua saída tem repetição "fictícia". Isto é o que recebo com o script abaixo -

   awk -f f1.awk /tmp/f1
    short
    hub
    wow
    hello
    a4-123
    b4-124
    yes
    yoo
    lol
    bad-girl
    good-guy
    lab
    dummy

    cat f1.awk 
    {
      n=split($1,a,"|")

      for(i=2; i<n; i++) {
        arr[a[i]] = a[i] 
      } 
    }   
    END{
      for (var in arr) 
        print(var)  
    }
    
por 30.09.2016 / 18:56