Pracowałem nad skryptem bash w celu wyszukania nazw definicji, a następnie pobrania dla nich wartości szesnastkowych i umieszczenia ich na liście. Kiedy już mam listę nazw, spróbuję wyszukać „#define [nazwa]” używając -w, aby zapewnić dokładne dopasowanie, a następnie awk „{print $ 3}”, aby pobrać wartość szesnastkową.

Jednak działa, jeśli wiersz w pliku nagłówkowym jest podobny do

a.h:#define [name] 0x0001 

Ale NIE działa, jeśli jest podobny do

a.h: #define [name] 0x0001 

Jak mogę to obejść? Próbowałem tego

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

Myślałem, że \s* zignoruje początkowe białe spacje przed #define, ale nie” t. Czy robię coś źle?

Komentarze

  • Myślę, że musisz użyć rozszerzonego grep lub flagę -E, aby użyć \s
  • Tak, ale uważam, że problem jest spowodowany przez wiodące białe znaki #define do przesunięcia z 1 $ na 2 $
  • Powinieneś lepiej opisać problem, trudno jest zrozumieć, co chcesz osiągnąć.

Odpowiedź

Po prostu użyj awk (używając grep wydaje mi się zbędne, ponieważ awk już może pasować do wyrażenia regularnego):

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

Przechodzenie wyrażenie bardziej szczegółowo:

$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 

Aby to uruchomić rekurencyjnie, np.

ponieważ awk musi otrzymać listę plików do operacji, możesz:

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

Komentarze

  • czy to również może obsługiwać cykliczne? (sprawdzanie * .h z podkatalogów)
  • Bardzo dobrze, to jest świetne. Na podstawie kilku sugestii i testów stwierdziłem, że grep -Ro '#define\s*\(.*\)' *.h działa. -o było trudne, aby uzyskać całą linię, ale jeśli po prostu powiesz mu, aby zawierał wszystko, co nastąpi później, mogę teraz po prostu użyć awk, aby uzyskać element 3., ponieważ grep zawiera nazwę pliku nagłówkowego, jeśli była spacja przed #define to by zepsuło.

Odpowiedź

Użyj grep -o, aby wydrukować tylko pasującą część wiersza.

Oczywiście ponownie usuń \s, ponieważ nie chcę tę część.

Komentarze

  • Problem polega na tym, że z -o teraz nie ' t pobierz wartość szesnastkową, ponieważ przechwytuje tylko #define i $p

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *