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
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
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.