長い変数からライブラリディレクトリを抽出する

長い変数からライブラリディレクトリを抽出する

コンパイル中に使用するライブラリを含む長い変数を宣言しました。

export LIBS="-L/usr/lib -lcurl -L/lib -lhdf5 -Wl,-rpath,/lib -L/usr/lib64 -lglpk -Wl,-rpath,/usr/local/tools/vtk-6.1.0/lib -L/usr/local/tools/vtk-6.1.0/lib -lvtkIOCore-6.1 -lvtkCommonCore-6.1 -lvtkCommonDataModel-6.1 -lvtkFiltersCore-6.1 -lvtkIOXML-6.1 -lvtkImagingCore-6.1 -lvtkIOImage-6.1 -lvtkImagingMath-6.1 -lz -L/g/g92/miguel/petsc-3.6.2/miguel-opt/lib -lpetsc -Wl,-rpath,/g/g92/miguel/petsc-3.6.2/miguel-opt/lib -lcmumps -ldmumps -lsmumps -lzmumps -lmumps_common -lpord -lscalapack -lHYPRE -L/usr/local/tools/openmpi-intel-1.8.4/lib -L/usr/local/tools/ic-14.0.174/composer_xe_2013_sp1.3.174/compiler/lib/intel64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -lml -llapack -lblas -lparmetis -lmetis -lX11 -lhwloc -lssl -lcrypto -lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lifport -lifcore -lm -lmpi -Wl,-rpath,/usr/local/tools/ic-14.0.174/lib -limf -lsvml -lirng -lipgo -ldecimal -lcilkrts -lstdc++ -lgcc_s -lirc -lpthread -lirc_s -Wl,-rpath,/usr/local/tools/openmpi-intel-1.8.4/lib -Wl,-rpath,/usr/local/tools/ic-14.0.174/composer_xe_2013_sp1.3.174/compiler/lib/intel64 -Wl,-rpath,/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -ldl -Wl,-rpath,/g/g92/miguel/code/libmesh_2D/lib -L/g/g92/miguel/code/libmesh_2D/lib -lmesh_opt"

ここで、-Lで始まるディレクトリを抽出したいと思います。私はこれを試みます:

printenv LIBS | grep -o '\b-L\w*'

しかし、これを実行している間は何も起こりません(ただ何が起こっているのか理解しようとしています)。

printenv LIBS | grep -o '\b-l\w*'

変数から「-linux」という単語だけを抽出します。次のような新しい変数を取得したいと思います。

/usr/lib /lib /usr/lib64-lglpk /usr/local/tools/vtk-6.1.0/lib ...

明らかに、私は正規表現についてよく知らず、使用されているさまざまなツール(grep、sed、awkなど)と説明なしで暗号化された正規表現を表示する回答のために混乱します。役に立つ参考資料を提供してもよろしいですか?上記のさまざまなツールで正規表現構文が一般的に使用されていますか?ありがとうございます。

ベストアンサー1

単語境界の定義を見てみましょう。

3 つの異なる場所が単語の境界として機能します。

  • 文字列の最初の文字の前に最初の文字が単語文字の場合
  • 文字列の最後の文字の後、最後の文字が単語文字の場合。
  • 文字列の2文字の間。そのうちの1つは単語文字で、もう1つは単語文字ではありません。

ダッシュも単語文字ではないため、単語ではない文字と一致させるダッシュの間に単語境界はありません。

また、例えばスラッシュは単語ではなく文字でもあるためパスにスペースがないため、一致するのではなく、一致する方が\w*敏感になります[^ ]*しかし、部分一致も除外したいので、PCREをサポートするバージョンをgrep使用しない限り、作業に適したツールではありません。grep

printenv LIBS | grep -Po '(^| )-L[^ ]*'
% printenv LIBS | grep -Po '(^| )-L\K/[^ ]*'
/usr/lib
/lib
/usr/lib64
/usr/local/tools/vtk-6.1.0/lib
/g/g92/miguel/petsc-3.6.2/miguel-opt/lib
/usr/local/tools/openmpi-intel-1.8.4/lib
/usr/local/tools/ic-14.0.174/composer_xe_2013_sp1.3.174/compiler/lib/intel64
/usr/lib/gcc/x86_64-redhat-linux/4.4.7
/g/g92/miguel/code/libmesh_2D/lib

ただし、これはスペースを含まないパスに依存し、ダッシュを含まないパスに依存することも同様に間違っています。

一般に、この文字列を解析する安全な方法はありません。

私の提案は、パスを配列に手動で保存することです。

もう一度考えると、ルートを正しく解釈するためにルートの潜在的なスペースが逃げると想像しています。

もしそうなら、次は安全でしょう。

printenv LIBS | grep -Po '(^| )-L\K\/.*?(?=([^\\] |$))'
% export LIBS='-L/path\ with\ spaces -L/another\ path\ with\ spaces'
% printenv LIBS | grep -Po '(^| )-L\K\/.*?(?=([^\\] |$))'
/path\ with\ space
/another\ path\ with\ spaces

おすすめ記事