Tenho trabalhado em um script bash para pesquisar nomes de define e, em seguida, pegar os valores hexadecimais para eles e colocá-los na lista. Assim que tiver a lista de nomes, tentarei pesquisar por “#define [nome]” usando -w para garantir a correspondência exata e, em seguida, awk “{print $ 3}” para pegar o valor hexadecimal.

No entanto, funciona se a linha no arquivo de cabeçalho for semelhante a

a.h:#define [name] 0x0001 

Mas NÃO funciona se for semelhante a

a.h: #define [name] 0x0001 

Como posso contornar isso? Eu tentei isso

grep -nrw "\s*#define[[:space:]]*$p" . --include=*.h | awk "{ print $3 }" 

Achei que \s* iria ignorar o espaço em branco antes de #define mas não faz. Estou fazendo algo errado?

Comentários

  • Acho que você precisa usar grep estendido ou o sinalizador -E para usar \s
  • Sim, mas acredito que o problema vem do espaço em branco à esquerda, causando #define a ser mudado de $ 1 para $ 2
  • Você deve descrever o problema melhor, é difícil entender o que você deseja alcançar.

Resposta

Basta usar awk (usando grep parece redundante para mim, uma vez que awk já pode corresponder a uma expressão regular):

awk "$0~/\s*\#define\s*\[.*\]\s*.*/ {print $3}" *.h 

Percorrendo a expressão em mais detalhes:

$0 ~ /regexp/ # look for the regular expression in the record \s* # whitespace, any number of times \#define # literal string, "#" has to be scaped \s* # same as above .* # any character, any number of times, this is # your hex code and you can refine the regex here { print $3 } # print the third field if the record matches 

Para que isso seja executado recursivamente, por exemplo,

uma vez que awk precisa de uma lista de arquivos para operar, você poderia:

find . -type f -name "*.h" \ -exec awk "$0~/\s*\#define\s*\[.*\]\s*.*/ {print $3}" {} \; 0x0002 0x0003 0x0001 

Comentários

  • isso pode lidar com recursiva também? (verificando * .h nos subdiretórios)
  • Muito bem, isso é incrível. Com base em algumas sugestões e testes, descobri que grep -Ro '#define\s*\(.*\)' *.h funciona. -o foi complicado obter a linha inteira, mas se você apenas disser para incluir qualquer coisa que vier depois, posso agora apenas usar o awk para obter o elemento 3. já que grep inclui o nome do arquivo de cabeçalho, se houver um espaço antes de #define iria bagunçar tudo.

Resposta

Use grep -o para imprimir apenas a parte correspondente da linha.

Obviamente, retire a \s parte novamente, porque você não quero essa parte.

Comentários

  • O problema é que com -o, agora eu não ' t obtenha o valor hexadecimal, uma vez que captura apenas #define e $p

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *