Extraindo texto de um arquivo de texto no bash

3

Eu tenho um arquivo de texto grande, que é tudo uma linha. No texto há várias seções que se parecem com foo=12345 e eu preciso extraí-las todas como linhas separadas, ignorando o resto do arquivo.

Por exemplo:

random junk foo=12345 more junk random junk foo=2345 junk foo=7654 junk random foo=5432 junk

O que eu quero sair é:

12345
2345
7654
5432

Eu sei escrever o regex para extrair o foo=([0-9]+) , mas não sei como aplicar isso ao texto e obter as linhas no bash.

    
por Roger Gilbrat 26.02.2012 / 20:41

3 respostas

3
$> echo "random junk foo=12345 more junk random junk foo=2345 junk foo=7654 junk random foo=5432 junk" | grep --only-matching --perl-regexp "(?<=foo=)[0-9]+"
12345
2345
7654
5432

O que fizemos aqui é usar lookbehind regex em "(?<=foo=)[0-9]+" .

    
por 26.02.2012 / 20:45
4

Eu usaria awk para analisar a longa linha em registros.

awk 'BEGIN{FS="=";RS=" "}/^foo=/{print $2}'

Isso define cada "palavra" como um registro separado e, dentro dessa palavra, para separar campos com "=". Em seguida, apenas a saída do lado direito do '=' quando o lado esquerdo é "foo". Precisa usar o regexp em vez de $1=="foo" , pois, se não houver nenhum '=', o primeiro campo é igual ao registro inteiro.

    
por 26.02.2012 / 21:18
1

Você pode fazer isso apenas com construções de shell: leia os dados em uma variável e, em seguida, divida essa variável nos caracteres em $IFS (espaço em branco por padrão) e mantenha os fragmentos desejados. Uma substituição de variável fora de aspas duplas sofre a divisão de palavras (que queremos aqui) e a geração de nome de arquivo (a.k.a. globbing, que não queremos), portanto, desative a globbing com set +f primeiro.

set +f
for x in $(cat /path/to/file); do
  case "$x" in
    foo=*) echo "${x#*=}";;
  esac
done
set -f

Em vez de chamar cat , você pode usar o read builtin.

set +f
read -r line </path/to/file
for x in $line; do …
    
por 27.02.2012 / 01:29