Grep と先行スペースを無視

Grep と先行スペースを無視

私は定義された名前を検索し、その名前の16進値を取得してリストに入れるためにbashスクリプトを書いてきました。名前のリストがある場合は、-wを使用して "#define [name]"を検索して正確な一致を確認し、awk '{print $3}'を使用して16進値を取得します。

ただし、ヘッダファイルの行が次のような場合

a.h:#define [name] 0x0001

しかし、もしそれが次のような場合

a.h:    #define [name] 0x0001

この問題をどのように解決できますか?私はこれを試しました

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

\s*以前は先行スペースは無視されたと思いましたが、#defineそうではありません。私は何が間違っていましたか?

ベストアンサー1

使用してくださいawk(正規表現が既に一致する可能性があるため、使用がgrep重複しているようです)。awk

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

この式をより詳しく分析してください。

$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

これを再帰的に実行するには、次のようにします。

mkdir -p a/b/c
echo "   #define [name] 0x0001" > a/a.h
echo "   #define [name] 0x0002" > a/b/b.h
echo "   #define [name] 0x0003" > a/b/c/c.h
tree
.
└── a
    ├── a.h
    └── b
        ├── b.h
        └── c
            └── c.h

3 directories, 3 files

awk作業するファイルのリストを提供する必要があるため、次のことができます。

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

おすすめ記事