バックスラッシュ付きawk FS

バックスラッシュ付きawk FS

find . -maxdepth 1 -not -type d 次の出力を生成するコマンドを使用します。./filename.1.out

findコマンドの出力awkを。以下を使用して動作させました。./.

find . -maxdepth 1 -not -type d | gawk 'BEGIN { FS = "(\\./)|(\\.)" } ; { print NF }'

実際、最初の角かっこセットから最初のバックスラッシュを削除すると機能します。前任者:

find . -maxdepth 1 -not -type d | gawk 'BEGIN { FS = "(\./)|(\\.)" } ; { print NF }'

わかりません。私の質問は、以下を使用すると機能しない理由です。

find . -maxdepth 1 -not -type d | gawk 'BEGIN { FS = "(\./)|(\.)" } ; { print NF }'

「動作しない」という言葉は、NFが2番目の括弧が正規表現であるかのように数値を返すことです。文字(すべてのタイプの文字と一致) たぶん私自身の質問に答えているかもしれませんが... コマンド/動作を見ると初期バックスラッシュが無視されるようです。実際に警告エスケープシーケンスメッセージがあります\。通常の「.」として扱われます。しかし、NF印刷を始めるまで、それが何をしているのか理解していませんでした。

実際には...エスケープシーケンスのawkドキュメント(https://www.gnu.org/software/gawk/manual/html_node/Escape-Sequences.html#Escape-Sequences)説明する:

バックスラッシュ文字自体は通常含めることができない別の文字なので、\\文字列または正規表現にバックスラッシュを使用する必要があります。

したがって、ドル記号に一致する正規表現を作成するにはFS="\\$"

この記事を投稿する本来の意図は、なぜこのようなことが起こるのかを尋ねようとすることです。それから私は信じる私はいくつかを一つにまとめたかもしれません。間違っていたら訂正してください。

答え1

値はFS2回スキャンされます。 1つ目は文字列値で、2つ目はEREでスキャンされます(参照:語彙ルール)。

また、POSIX は、、、、のいずれかではなく、8 進数である、、、、、、、、の\c動作を指定しません。したがって、文字列がEREに渡されるのか、EREに渡されるのかはわかりません。c"/\dddd\abfnrtv\c\cc

gawk、、、nawkBrian Kernighan自身のバージョンあなたにc、そして同時にmawkあなたに\c

$ for AWK in gawk mawk nawk bk-awk; do
  printf '<%s>\n' "$AWK"
  echo | "$AWK" -F '\.' '{print FS}'
done
<gawk>
gawk: warning: escape sequence `\.' treated as plain `.'
.
<mawk>
\.
<nawk>
.
<bk-awk>
.

\\常にとして認識されるので\安全です\\c

$ for AWK in gawk mawk nawk bk-awk; do
printf '<%s>\n' "$AWK"; echo | "$AWK" -F '\\.' '{print FS}'
done
<gawk>
\.
<mawk>
\.
<nawk>
\.
<bk-awk>
\.

の文字列値がある\\cので、\cEREとして使用すると、目的の結果が得られます。

答え2

\xこれは正規表現(ほとんどのシェルやCなど)で処理される前に二重引用符で囲まれた文字列の文字になるため、実際に入力する必要があり\\.ます\.

|これをテストしてみましょう(代替演算子の優先順位が最も低いため、括弧は必要ありません)。

$ echo ./a.b.c | gawk 'BEGIN { FS = "\.|\./" } { for (i=1; i<=NF; i++) { print i ": " $i } }'
gawk: cmd. line:1: warning: escape sequence `\.' treated as plain `.'
1: 
2: 
3: 
4: 
5: 
6: 
7: 

この警告は、文字列のエスケープシーケンスが重複していることを示します。したがって、FSが行うことは、.|./各文字を分割して空のフィールドを作成することです。

今倍増してください\

$ echo ./a.b.c | gawk 'BEGIN { FS = "\\.|\\./" } { for (i=1; i<=NF; i++) { print i ": " $i } }'
1: 
2: a
3: b
4: c

関連情報