3

多数の M4 マクロ ファイルがあり、そこからファイル パスの 1 つのインスタンスが存在する場合はそれを抽出します。

各ファイルには、次のいずれかの単一行があります

define(`XSETROOT', `some_command with parameters SOME_DIR/subdir1/subdir2/filename')

または2行にまたがる

define(`XSETROOT', dnl
`some_command with parameters SOME_DIR/subdir1/subdir2/filename')

またはまったくエントリがありません。

だから私は行が始まるのを見つけたい

define(\`XSETROOT',

そして、同じ行または次の行から、「スペース」と「一重引用符」で囲まれた文字列を抽出します。

SOME_DIR/subdir/subdir/filename

複数の sed 呼び出しに頼らずにこれを行うことはできますか?

追加情報 (以下のコメント欄のフォーマットが機能していないようです) --

すべてが同じ行にある簡単なケースでは、引用符の問題は適切な引用符/引用符解除によって克服でき、この式は機能します

sed -ne 's|define(`XSETROOT'\'',.*`.* \(.*\)'\''.*|\1|p' file.m4

さらに詳しい情報 -

MvG さんが複数行処理のやり方を教えてくれたおかげで、データが 2 行に分割されている場合、この式が機能します。

sed -ne '/define(`XSETROOT/{n;s|`.* \([^'\'']*\)'\'').*|\1|p}' file.m4

しかし、疑問が残ります。1 行または 2 行のデータで機能する式を構築することは何らかの方法で可能でしょうか。それとも、返された文字列があるかどうかを確認するために 1 つを試して、そうでない場合は別の行を試して確認する必要がありますか?それが文字列を返す場合は?

4

3 に答える 3

0

使用できる場合は、次のようawkに機能する可能性があります。

awk -F "[`']" 'BEGIN { RS=")" } { print gensub(".* ","","g",$4) }' INPUTFILE

(Ideone.com が CLI 引数をサポートしていないのとほぼ同じ) in action here を参照してください

説明:

  1. -F "[`']"フィールド区切り文字を[`'](これらの 2 つの引用符のいずれか)の正規表現に設定します
  2. RS=")"レコードセパレーターを設定して、この方法で複数行のレコードを作成できるようにします
  3. gensub(".* ","","g",$4)最後のスペースの後の 4 番目のフィールドからすべてを返します
于 2012-09-04T21:09:33.227 に答える
0

これを試して:

sed -n "/define(\`XSETROOT'/{/dnl/N;s/.* //;s/'.*//;p}"
  • 現在の行に が含まれていない限り、何もしませんdefine(`XSETROOT'
  • 行に も含まれている場合はdnl、次の行を追加します。
  • 最後のスペースまですべてを削除します。
  • 最後の単一引用符の後のすべてを削除します。
  • 残りの文字列を出力します。

N実際に a が存在するケースへのコマンドの制限は、dnl2 つの目的に役立ちます: ファイルの最後で 1 行の定義が一致することを許可し、最初の行が 1 行しかない場合に 2 つの後続の定義を許可します。

于 2012-09-04T21:11:31.180 に答える