GREP para padrão e remover todos os caracteres indesejados antes ou depois do padrão

0

Eu tenho um conjunto de arquivos em um diretório. E cada arquivo terá uma linha chamada ---PUBG-xxxxx-- ou ---PUBG-xxxxx, PUBG-yyyyy ---- . Abaixo está a saída do comando grep.

grep "^--" FILE*.sql | grep "PUBG"

FILE1.sql:---PUBG-10901--
FILE2.sql:---PUBG-11617--
FILE3.sql:---PUBG-11625--
FILE4.sql:--PUBG-11724--
FILE5.sql:---PUBG-11720, PUBG-11406---
FILE6.sql:---PUBG-11403---
FILE7.sql:---PUBG-12021--
FILE8.sql:---PUBG-12207--
FILE9.sql:---PUBG-12270--
FILE10.sql:---PUBG-12552--
FILE11.sql:--- PUBG-14284--
FILE12.sql:--- PUBG-10908--
FILE13.sql:--- PUBG-15136---
FILE14.sql:--- PUBG-15163---
FILE15.sql:--- PUBG-15166---
FILE16.sql:-- PUBG-15059 --
FILE17.sql:-- PUBG-15252 --

O PUBG e seus números serão aleatórios. Tudo que eu preciso é o nome do arquivo e seu valor PUBG associado sem -- antes ou depois do PUBG e seu valor. Também pode haver vários PUBGs como em FILE5.sql:---PUBG-11720, PUBG-11406--- . Eu escrevi o conjunto abaixo para loop.

for (i in 'grep "^--" FILE*.sql | grep "PUBG"')
do
    FILE_NAME='echo ${i} |  awk -F ":" {'print $1'}'
    PUBG_NO='echo ${i} | awk -F "PUBG-" {'print "PUBG-" $2'}'
    echo ${FILE_NAME}
    echo ${PUBG_NO}
done

Mas a saída de amostra para PUBG_NO é PUBG-15166--- para FILE15.sql e é PUBG-11720, para FILE5.sql .

Preciso de todos os valores de PUBG em um arquivo para determinado FILE_NAME sem -- . O valor PUBG de FIlE5.sql pode ser PUBG-11720, PUBG-11406 Como esse loop pode ser melhorado para buscar os resultados exatos.

    
por sabarish jackson 27.11.2018 / 11:30

3 respostas

1

Você não precisaria escrever um loop. Você poderia apenas canalizar sua saída para sed. Minha tentativa é a seguinte:

grep "^--" FILE*.sql | grep "PUBG" | sed -E 's/--+\ ?//g'

O que daria

FILE1.sql:PUBG-10901
FILE2.sql:PUBG-11617
FILE3.sql:PUBG-11625
FILE4.sql:PUBG-11724
FILE5.sql:PUBG-11720, PUBG-11406
FILE6.sql:PUBG-11403
FILE7.sql:PUBG-12021
FILE8.sql:PUBG-12207
FILE9.sql:PUBG-12270
FILE10.sql:PUBG-12552
FILE11.sql:PUBG-14284
FILE12.sql:PUBG-10908
FILE13.sql:PUBG-15136
FILE14.sql:PUBG-15163
FILE15.sql:PUBG-15166
FILE16.sql:PUBG-15059 
FILE17.sql:PUBG-15252 
FILE14.sql:PUBG-15163
FILE15.sql:PUBG-15166
FILE16.sql:PUBG-15059 
FILE17.sql:PUBG-15252 

Aqui, estou usando um comando sed substitue que assume a forma de

's/regular expression/substition/flag'

Para detalhar o comando:

  • A expressão regular "- + \?" é o padrão que você deseja localizar e selecionar. Isso pode ser lido como "Encontrar um padrão que tenha" - "seguido por um ou mais" - "consecutivos, seguido por zero ou um" ". Isso corresponderá a" - "," --- "e" - - "na sua saída. Observe que você precisará do sinalizador -E para sed a fim de reconhecer esses quantificadores. Aqui está uma referência rápida para atualizar os quantificadores regex como? E +
  • Aqui, o espaço de substituição é deixado vazio. Isso substituirá os padrões encontrados por nada e é um método eficaz para eliminar sua saída.
  • O sinalizador "g" indica que a pesquisa será global. Sem isso, a substituição só acontecerá na primeira partida em cada linha. Adicionar o g irá garantir que todas as instâncias desse padrão em cada linha sejam substituídas por nada.

Você também pode aplicar esses conceitos ao seu comando grep inicial para executar apenas uma pesquisa.

grep -E "^--+\ ?PUBG" FILE*.sql | sed -E 's/--+\ ?//g'
    
por 27.11.2018 / 13:55
0

Seguindo o AWK:

awk '
BEGIN { RS="[,\n]"; }
/PUBG-[0-9][0-9][0-9][0-9][0-9]/ { match($0,/PUBG-[0-9][0-9][0-9][0-9][0-9]/); print(FILENAME ":" substr($0,RSTART,RLENGTH)); }
' FILE*.sql

Irá dar esta saída:

FILE11.sql:PUBG-14284
FILE1.sql:PUBG-10901
FILE3.sql:PUBG-11625
FILE5.sql:PUBG-11720
FILE5.sql:PUBG-11406

São levados apenas 5 arquivos em consideração:

$ ls FILE*.sql
FILE11.sql  FILE1.sql  FILE3.sql  FILE5.sql
    
por 27.11.2018 / 11:44
0
awk -F, '/^--/ && /PUBG/ {
    for (i=1; i<=NF; ++i) {
        sub("^[- ]*", "", $i)
        sub("[- ]*$", "", $i)
        print FILENAME, $i
    } }' FILE*.sql

Isso passaria pelos arquivos SQL originais e substituiria seu pipeline.

O código awk extrai todas as linhas que começam com -- e que contém a string PUBG . Para cada linha, ela passa pelas entradas delimitadas por vírgula e retira qualquer traço e caractere de espaço do início e do final de cada um. Após o corte, ele imprime a string PUBG-NNNN resultante, precedida do nome do arquivo em que foi encontrada.

    
por 27.11.2018 / 14:16