
内容は次のテストファイルを受け取りました。
a -*- b
使用しましたがawk 'BEGIN {FS="*"} {print $2}' test
印刷されます。
- b
正しい!しかし、 を使用すると、次のようなawk 'BEGIN {FS="-*-"} {print $2}' test
結果が得られます。
*
私はFS
正規表現がサポートされていることを知っているので、以前にそれを追加し、\
まだこれを実行して*
次awk 'BEGIN {FS="-\*-"} {print $2}' test
のようになりました。
*
幸い、私は半年前にブログを始めました。awk 'BEGIN {FS="-[*]-"} {print $2}' test
この場合に使用する必要があると言われています。したがって、私は以下を得る:
b
また正解!
*
しかし、なぜFSがそれを理解できるのか、理解できないのか-*-
、-\*-
そしてついに理解できるのか、本当に混乱しています-[*]-
。
メカニズムは何ですか?
答え1
1文字より長い場合はFS
正規表現として扱われます。 ofはFS
単に*
固定文字列として扱われますが、FS
ofは(one or more)と同等の-*-
正規表現です。したがって、自分を普通の人物として見ることを許可する必要があります。そして両方ともこれを行うことができます。ただし、文字列は解析されます。-*-
-+
-
*
-\*-
-[*]-
FS
二重- 割り当て時に一度、分割時に一度FS
。そのため、エスケープ文字\
もエスケープする必要があります。\
$ awk -F '-\\*-' '{print $2,FS}' test.txt
b -\*-
$ awk -F '-\*-' '{print $2,FS}' test.txt
awk: warning: escape sequence `\*' treated as plain `*'
* -*-
答え2
muruの答えの重要な点の1つは、正規表現にバックスラッシュを追加するには二重バックFS
スラッシュを作成する必要があることです\\
。これは、バックスラッシュが2つの異なるレベルでエスケープ文字として使用されるためです。
文字列の単一のバックスラッシュは次の文字をエスケープすることで処理されるため、正規表現で単一のバックスラッシュを取得するにはバックスラッシュ自体をエスケープする必要があります。それからそれバックスラッシュは正規表現で次の文字をエスケープします。
FS='ax\*'
コメントで述べたように、asとasの間に違いはありませんが、awkFS='ax*'
は警告を出力します。テキストを入力するには、will Split onのように二重バックスラッシュを使用する必要があります。\*
*
*
FS
FS='ax\\*'
ax*
おそらく、いくつかの例でこれをより明確に理解することができます。
#!/usr/bin/env bash
s='123abcd
123axbcd
123axxbcd
123ax*bcd
123ax**bcd'
printf "%s\n\n" "$s"
awk -F 'ax*' 'BEGIN{printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk 'BEGIN{FS="ax*"; printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk -F 'ax\*' 'BEGIN{printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk 'BEGIN{FS="ax\*"; printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk -F 'ax\\*' 'BEGIN{printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk 'BEGIN{FS="ax\\*"; printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
出力
123abcd
123axbcd
123axxbcd
123ax*bcd
123ax**bcd
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
awk: warning: escape sequence `\*' treated as plain `*'
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
awk: warning: escape sequence `\*' treated as plain `*'
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
FS=[ax\*]
[123abcd] []
[123axbcd] []
[123axxbcd] []
[123] [bcd]
[123] [*bcd]
FS=[ax\*]
[123abcd] []
[123axbcd] []
[123axxbcd] []
[123] [bcd]
[123] [*bcd]
答え3
区切り文字の内側で"
バックスラッシュをエスケープする必要があります。
$ echo 'a -*- b' | awk 'BEGIN {FS="-\\*-"} {print $2}'
b
正規表現はFS変数に渡されるため、\\
二重引用符内の二重引用符は単一のバックスラッシュで解析され、結果の正規表現は入力文字列に適用されます。