Sed / Awk - Encontre uma string com exatamente n caracteres

3

Olhando através das páginas man para sed, awk e grep, não consigo encontrar uma maneira de procurar por uma string com exatamente n caracteres.

Dado o seguinte arquivo de texto, quero extrair apenas 6982a9948422

ID                  IMAGE               COMMAND                
CREATED             STATUS              PORTS
6982a9948422        ubuntu:12.04        apt-get install ping   
1 minute ago        Exit 0

O valor estará sempre na primeira coluna e é sempre 12 caracteres alfanuméricos.

Aqui está o que estou tentando até agora.

 cat /tmp/test | awk {'print $1'} | sed 's/.*\([0-9],[A-Z],[a-z]\{12\}\).*//g'

Qual seria uma maneira de extrair apenas 6982a9948422 do texto acima?

    
por spuder 26.01.2014 / 05:32

9 respostas

9
awk 'length($1) == 12 { print $1 }' file

O programa é bastante auto-documentável e evita o martelo regex.

awk -v f=1 '$f ~ /^[[:alnum:]]{12}$/ { print $f }' file

Ou mova-se para longe com o que precede se quiser considerar apenas os primeiros campos (campos delimitados por espaços em branco) que consistem apenas em caracteres alfanuméricos.

Com as implementações de awk que não suportam as expressões regulares de {x,y} interval, você pode alterá-lo para:

awk -v f=1 'length($f) == 12 && $f !~ /[^[:alnum:]]/ { print $f }' file
    
por 26.01.2014 / 15:14
4

Isso pesquisará e imprimirá todas as cadeias alfanuméricas que começam no início de uma linha e têm exatamente 12 caracteres.

grep -o -w -E '^[[:alnum:]]{12}'

Para usuários do macOS. Instale o GNU grep para que isso funcione. Pode ser feito usando o homebrew .

    
por 26.01.2014 / 05:45
1

Você pode usar grep com o recurso PCRE. Está disponível na maioria das versões mais recentes de grep .

$ grep -oP "^[[:alnum:]]{12}" test.txt
6982a9948422

Isso fornecerá a você todas as correspondências com 12 caracteres e incluirá caracteres válidos em palavras, [a-zA-Z0-9] .

    
por 26.01.2014 / 05:43
1

Outra solução, usando o delimitador de fim de palavra, não é aparente em nenhuma das soluções acima:

egrep '^[[:alnum:]]{12}\>' filename
    
por 26.01.2014 / 15:55
1

Solução AWK

awk '{match( $1, /[0-9A-Za-z]{12}/, arr) }; { printf arr[0] }' inputFile

OR

awk '$1 ~ /[0-9A-Za-z]{12}/{print $1}' inputFile
    
por 26.01.2014 / 07:11
0

Outros deram respostas para o seu caso de teste específico em que a string em questão está no início da linha. Essas soluções imprimem todas strings que consistem em 12 caracteres de palavras consecutivos:

perl -lne 'print for /\b(\w{12})\b/g;' file
grep -oP '\b(\w{12})\b' file
    
por 26.01.2014 / 17:29
0

Não grep , awk , etc., apenas shell POSIX puro:

while read x y ; do case "$x" in ????????????) echo $x ;; esac ; done < test

Saída:

6982a9948422

Se a correspondência precisar ser estritamente alfanumérica, sempre haverá :

while read x y ; do case "$x" in \
    [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]) echo $x ;; \
                    esac ; \
done < test
    
por 03.08.2016 / 18:58
0

Eu modificaria sua própria solução. Em vez de excluir qualquer $1 que não corresponda ao regexp necessário, use grep para filtrá-los:

awk '{print $1}' /tmp/test | grep -iE '^[a-z0-9]{12}$'

Como alternativa, em sed puro:

sed 's/^\([a-zA-Z0-9]\{12\}\)[ \t]\+.*//' /tmp/test     
    
por 26.01.2014 / 16:30
-2

Isso processará qualquer linha que tenha 12 caracteres alfanuméricos e imprima o primeiro campo:

awk '/[[:alnum:]]{12}/ {print $1}' file
    
por 03.08.2016 / 18:09

Tags