Como grep “a” e “aa” depois de um número?

4

Meu arquivo .txt tem linhas como as seguintes:

1a
1aa
2a
2aa

Eu quero fazer uma tarefa específica para o lado "a" e outra tarefa específica para o lado "aa". Para ser mais preciso e claro, a tarefa que estou fazendo para o lado "a" não deve funcionar para o lado "aa" e, da mesma forma, a tarefa que estou fazendo para o lado "aa" não deve funcionar para o lado "a".

Por exemplo:

  • Para o lado "aa", quero ir para um diretório
  • Para o lado "a", quero ir para mais de um diretório.

Como posso fazer isso no meu script?

    
por Deep Mukherjee 04.07.2017 / 10:24

5 respostas

10

grep -xE '[0-9]+a'

Grupos de linhas que consistem em x de um ou mais dígitos decimais seguidos por a .

grep -xE '[0-9]+aa'

Para a variante com aa .

-E é para expressões regulares estendidas necessárias para + . Com regexps básicos e sem -x , você pode fazer:

grep '^[0-9]\{1,\}a$'

^ e $ correspondendo respectivamente no início e no final da linha, e \{1,\} sendo o equivalente a BRE de ERE + (algumas grep implementações também suportam \+ para isso e você poderia use sempre [0-9][0-9]* ).

    
por 04.07.2017 / 10:36
3

Como a expressão regular a também corresponde a "aa", você deve manipular "aa" primeiro no seu script.

Outra opção é usar o regexp compatível com perl (PCREs), o grep tem uma opção -P para habilitá-los, o que vem com o aviso

This is highly experimental and grep -P may warn of unimplemented features

(pelo menos a versão que tenho, não sei se eles removeram a opção ou alteraram / removeram o aviso em versões mais recentes), ou você pode usar perl . Então, um regexp como /a(?!a)/ deve ser usado no caso "a".

    
por 04.07.2017 / 10:45
2
#!/bin/sh

while read word; do
    case "$word" in
        *aa)    printf 'Got double "a": %s\n' "$word"   ;;
        *a)     printf 'Got single "a": %s\n' "$word"   ;;
        *)      printf 'Got weirdness:  %s\n' "$word"   ;;
    esac
done <file.in

Executando isso com os dados de exemplo em file.in :

Got single "a": 1a
Got double "a": 1aa
Got single "a": 2a
Got double "a": 2aa

Você poderia estender isso com um loop sobre seus arquivos em torno do loop while existente:

#!/bin/sh

for name in ./*.in; do
    while read word; do
        case "$word" in
            *aa)    printf 'Got double "a": %s\n' "$word"   ;;
            *a)     printf 'Got single "a": %s\n' "$word"   ;;
            *)      printf 'Got weirdness:  %s\n' "$word"   ;;
        esac
    done <"$name"
done

Isso presume que os arquivos de entrada correspondam ao padrão *.in e estão localizados no diretório atual.

    
por 04.07.2017 / 11:53
1

Você pode combinar o sufixo aa com aa$ . A correspondência do sufixo a é um pouco mais difícil, pois logicamente o aa também termina com a . É por isso que você precisa de [^a]a$ para corresponder a um único. O [^a] é uma classe de caracter invertida, é todo caracter mas um a.

    
por 04.07.2017 / 13:58
0

Assumindo que você quer dizer zero ou mais dígitos no início de uma linha seguida por um a (ou dois dígitos, abordaremos mais tarde), então sim , este comando funcionará:

grep '^[0-9]*a'

Corresponde a todas as linhas no arquivo de entrada:

$ grep '^[0-9]*a' file
1a
1aa
2a
2aa

Se (e eu fornecer uma solução, se não é isso que você quer dizer) você quer dizer a linha inteira , então, isso funcionará:

$ grep   '^[0-9]*a$' file
$ grep -x '[0-9]*a'  file
1a
2a

Para forçar um ou mais dígitos , use um dos seguintes:

grep    '^[0-9][0-9]*a'
grep    '^[0-9]\{1,\}a'
grep -E '^[0-9]+a'

Mas se o que você quer dizer é combinar uma linha que começa com um dígito, tem um a e possivelmente muitas outras coisas, então: use:

$ grep '^[0-9]\{1,\}a[^a]' file

Que, para um arquivo como este:

$ cat file
1a
1aa
123a
1234aa
a
aa
2a
2aa
123afgr
123aahtr

Aceita apenas estas linhas:

$ grep -E '^[0-9]+a([^a]|$)' file
1a
123a
2a
123afgr

Existem várias soluções possíveis para dois a , e este é um exemplo simples:

$ grep -E '^[0-9]+aa([^a]|$)' file
1aa
1234aa
2aa
123aahtr

E, se você remover a start anchor, a correspondência será ancorada até o final:

$ cat file
1a
1aa
123a
1234aa
a
aa
2a
2aa
123afgr
123aahtr
abc20cb1aa
abc20cb1a
abc20cb2aa
abc20cba

$ grep -E '[0-9]+aa([^a]|$)' infile
1aa
1234aa
2aa
123aahtr
abc20cb1aa
abc20cb2aa
    
por 04.07.2017 / 23:11

Tags