2

次のように行を変更する sed regex コマンドを作成するのに苦労しています。

In file included from dira/file_a.h:8, dire/file_e.h:9, and dirf/file_f.h:10,
             from dirb/file_b.h:6,
             from /existing/abs/path/dirb/file_b.cc:6:
dirc/file_c.h:88: error: 'eqn_count_t' does not name a type
dirc/file_c.h:95: error: 'wave_count_t' does not name a type
dirc/file_c.h:104: error: ISO C++ forbids declaration of 'WmHyperbolicEqnSet' with no type

この目的の出力に:

In file included from /abspaths/dira/file_a.h:8, /abspaths/dire/file_e.h:9, and /abspaths/dirf/file_f.h:10,
             from /abspaths/dirb/file_b.h:6,
             from /existing/abs/path/dirb/file_b.cc:6:
/abspaths/dirc/file_c.h:88: error: 'eqn_count_t' does not name a type
/abspaths/dirc/file_c.h:95: error: 'wave_count_t' does not name a type
/abspaths/dirc/file_c.h:104: error: ISO C++ forbids declaration of 'WmHyperbolicEqnSet' with no type

それで、

  • .h で終わる相対パス + ファイル名のみに一致
  • スラッシュで始まる行には一致しません (したがって、すでに絶対パスになっています)。
  • 行ごとに複数の出現に一致
  • Mac OS Xの BSD sed コマンドで動作するコマンドが必要であることが明らかになりました。

必要な正規表現と sed コマンドは何ですか?

エラー/警告を含むヘッダーファイルが含まれていると、絶対パスではなく相対パスが参照されたエラーストリーム出力が生成されるため、gcc 出力を変更しようとしています。私の XCode IDE が外部ビルド システムを呼び出すと、.h ファイルで発生するエラーは「クリック可能」ではありません。

4

3 に答える 3

3

最終編集

私はついに、1つのコマンドだけで、両方で機能するそのようなコマンドを正常に作成しました:

sed 's/^\(.* \)\{0,1\}\([^/ ][^ ]\{1,99\}\.h\)/\1\/abspath\/\2/;' testfile.txt

そして、マルチマッチをサポートするために... Macでも(@sudo_Oからいくつかの単純化のアイデアがあります):

sed -E -e :a -e 's/^(.* )?([^/][^ ]+\.h)/\1\/abspath\/\2/' -e ta testfile.txt 

しかし Mac のseddontの実装は;、コマンド セパレータとしてサポートされていません。したがって、複数の-eコマンド フィールドを使用する必要があります。

それらをテストするためにtextfile.txt、次のコマンドで変更しました。

sed -e '4s/^.*$/& &/' -i.bak testfile.txt

(Macでも動作します)

2 つの部分があり、最初は任意の文字列を数えることができますが、スペースで終わります... 0 回または 1 回。2 番目の部分は、スペースまたはスラッシュで始めてはならず、スペース以外のものを含めることができ、. で終わる必要があり.hます。一致する場合、最初の部分 (先頭にスペースが含まれますが、0 回の場合は空になる可能性があります)の後/abspath/には、2 番目の部分よりも , が続く必要があります。

古い

これは機能しませんか?

Mac 用に変更された編集:

sed 's/ \([^/ ][^ ]\{1,99\}\.h\)/ \/abspath\/\1/;' testfile.txt

Mac でも Linux でも同じように動作します。に置き換えまし+{1,99}

申し訳ありませんが、私は質問を正しく読んでいませんでした。これは両方でうまくいきます:

sed 's/^\([^/ ][^ ]\{1,99\}\.h\)/\/abspath\/\1/;
     s/ \([^/ ][^ ]\{1,99\}\.h\)/ \/abspath\/\1/;' testfile.txt
于 2012-12-30T23:09:57.780 に答える
2

Mac および Linux フレンドリー:

sed -E 's/^([^/][a-zA-Z/_]+\.h)/\/abspaths\/\1/;s/ ([^/][a-zA-Z/_]+\.h)/ \/abspaths\/\1/g' file

目的の出力に一致します。

In file included from /abspaths/dira/file_a.h:8, /abspaths/dire/file_e.h:9, and /abspaths/dirf/file_f.h:10,
             from /abspaths/dirb/file_b.h:6,
             from /existing/abs/path/dirb/file_b.cc:6:
/abspaths/dirc/file_c.h:88: error: 'eqn_count_t' does not name a type
/abspaths/dirc/file_c.h:95: error: 'wave_count_t' does not name a type
/abspaths/dirc/file_c.h:104: error: ISO C++ forbids declaration of 'WmHyperbolicEqnSet' with no type

説明:

置換が行の先頭にない場合に必要な余分なスペースを考慮するために、2 つの置換が必要です。

s/^([^/][a-zA-Z/_]+\.h)/\/abspaths\/\1/;   # First substitution for start of line 
s/ ([^/][a-zA-Z/_]+\.h)/ \/abspaths\/\1/g  # Second for non-start of line

# Match (first substitution)
s/
^             - start of line
(             - capture group 
[^/]          - not a forward slash 
[a-zA-Z/_]+   - one or more letter, forward slash or underscore
\.h           - the extension (escaped) 
)             - end capture group 
# Replace with 
/
\/abspaths\/  - the literal string /abspaths (slashes escaped)
\1            - the captured group 
/;
# Match (second substitution)
s/
' '           - not start of line but a single space (used quotes here for space)
(             - capture group 
[^/]          - not a forward slash 
[a-zA-Z/_]+   - one or more letter, forward slash or underscore
\.h           - the extension (escaped) 
)             - end capture group 
# Replace with 
/
' '           - put the single space back
\/abspaths\/  - the literal string /abspaths (slashes escaped)
\1            - the captured group 
/g            - global flag

または、( F.Hauriに基づく) 1 つの置換を実行するだけでは、1 行につき 1 つの一致に対してのみ機能します。

sed -E 's/^(.* )?([^/][^ ]+\.h)/\1\/abspath\/\2/' file

複数の一致の場合、分岐sedがサポートされます:

sed -E ':a;s/^(.* )?([^/][^ ]+\.h)/\1\/abspath\/\2/;ta' file
于 2012-12-30T22:44:47.483 に答える
0

これを試して:

sed "s|\([^\s]*\.h\)|/abspath/\1|" <testfile.txt

そして絶対パスを無視するには:

sed "s|^\([^/][^\s]*\.h\)|/abspath/\1|" <testfile.txt
于 2012-12-30T22:28:34.230 に答える