GNU awk の man ページを見てみましょう:
<ブロック引用>
FS
— 入力フィールド区切り文字。デフォルトではスペースです。 フィールドを参照してください 、上。
フィールドへ セクション!
<ブロック引用>
各入力レコードが読み取られると、gawk は FS
の値を使用して、レコードをフィールドに分割します。 variable をフィールド区切りとして使用します。 FS
の場合 は 1 文字で、フィールドはその文字で区切られます。 FS
の場合 がヌル文字列の場合、個々の文字が個別のフィールドになります。それ以外の場合は FS
完全な正規表現であることが期待されます。 FS
という特別な場合 は単一のスペースです。フィールドは一連のスペース、タブ、および/または改行で区切られています。
実用的なまとめはこちら すべての主要な Awk 実装に適用されます :
- GNU Awk (
gawk
) - デフォルトのawk
一部で Linux ディストリビューション - マウク (
mawk
) - デフォルトのawk
一部で Linux ディストリビューション (以前のバージョンの Ubuntu など) - BWK Awk - デフォルトの
awk
macOS を含む BSD ライクなプラットフォームで
すべての最近のバージョン これらの実装は field に関して POSIX 標準に従います セパレーター (ただし記録はしない) セパレーター)
用語集:
-
RS
input-レコードです セパレーター 、入力がレコードにどのように分割されるかを説明します :- POSIX で義務付けられているデフォルト値 改行です 、
\n
とも呼ばれます 下;つまり、入力は 行 に分割されます デフォルトで . awk
で のコマンド ライン、RS
-v RS=<sep>
として指定できます .- POSIX は
RS
を制限しています リテラルの 1 文字 値ですが、GNU Awk と Mawk は 複数文字 をサポートしています 拡張正規表現の値 (BWK Awk はしません それをサポートします)。
- POSIX で義務付けられているデフォルト値 改行です 、
-
FS
input-フィールドです セパレーター 、各レコードの方法を説明します フィールドに分割されています ; 拡張正規表現の可能性があります .awk
で のコマンドライン、FS
-F <sep>
として指定できます (または-v FS=<sep>
).- POSIX で義務付けられているデフォルト値は正式に スペース (
0x20
)、しかしそのスペースは文字通りではありません (唯一の)セパレータとして解釈されますが、特別な意味があります ;以下を参照してください。
デフォルト :
- すべての実行 スペース および/または タブ および/または改行 フィールド区切りとして扱われます
- 先行ランと後続ランは無視 .
デフォルトの入力レコード セパレータを使用することに注意してください (RS
)、\n
、改行通常 フィールド区切りとして画像を入力しないでください 、レコード自体がないため \n
を含む
フィールド セパレータとしての改行 登場 ただし、
RS
の場合 自分自身のレコードになる値に設定されます\n
を含む インスタンス (RS
の場合など) 空の文字列に設定されています;以下を参照してください)。- 一般的に 、
split()
の場合 関数は、明示的なフィールド区切り引数なしで文字列を配列要素に分割するために使用されます。- 入力レコード
\n
は含まれません デフォルトのRS
の場合のインスタンスsplit()
が有効です 別のソースからの複数行の文字列で明示的なフィールド区切り引数なしで呼び出された場合の関数 (例:-v
経由で渡される変数 オプションまたは疑似ファイル名として) 常に\n
を扱います フィールド区切りとして。
- 入力レコード
デフォルト以外の重要な考慮事項 :
-
空の割り当て 文字列を
RS
に 特別な意味を持つ :段落モードで入力を読み取ります 、入力が空でない行の実行によってレコードに分割されることを意味します 、先頭および末尾の空行は無視されます . -
何かその他を割り当てるとき リテラルよりも
FS
までのスペース 、FS
の解釈 根本的に変わる :- シングル 文字または指定された文字 set の各文字 認識されている個別 フィールド区切りとして - 走らない デフォルトと同様に、それの
- たとえば、
FS
を設定すると、[ ]
まで - 効果的に 1 つのスペースに相当します - すべての 個々 を引き起こします フィールド区切りとして扱われる各レコードのスペース インスタンス。 - ランニングを認識するため 、正規表現量指定子 (重複記号)
+
使用する必要があります。例:[\t]+
実行を認識します 単一の区切りとしてのタブの。
- たとえば、
- 先頭と末尾 セパレーターは無視されません 、代わりに empty を分離します フィールド。
FS
の設定 空の文字列に 各文字を意味します レコードの 独自のフィールド .
- シングル 文字または指定された文字 set の各文字 認識されている個別 フィールド区切りとして - 走らない デフォルトと同様に、それの
-
RS
の場合、POSIX で義務付けられているとおり 空の文字列に設定されています (段落モード)、改行 (\n
) も フィールド区切りと見なされる 、FS
の値に関係なく .
-P
で 有効でRS
空の文字列に設定 、\n
まだです フィールド区切りとして扱われます:
gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
-P
で 空でないRS
、\n
はフィールド区切りとして扱われません - これは廃止された動作です:
gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
修正予定 、GNU Awkメンテナーによると;バージョン 4.2 で期待 (時間枠は指定されていません)。
(@JohnKugelman と @EdMorton に敬意を表します。)
'[ ]+' は私のために動作します.Run awk -W version
awk バージョンを取得します。私のは GNU Awk 4.0.2
です .
# cat a.txt
tcp 0 0 10.192.25.199:65002 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:26895 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:18422 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8888 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50010 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50075 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8093 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8670 0.0.0.0:* LISTEN
たとえば、Listen ポートを取得したいとします。そのため、':' を追加した awk のデフォルトの区切り文字を使用する必要があります
# cat a.txt | awk -F '[ ]+|:' '{print $5}'
65002
26895
111
18422
22
8888
50010
50075
8093
8670
デフォルトの区切り文字をテストしたいだけなら、実行できます
# cat a.txt | awk -F '[ ]+' '{print $4}'
10.192.25.199:65002
127.0.0.1:26895
0.0.0.0:111
0.0.0.0:18422
0.0.0.0:22
10.192.25.199:8888
0.0.0.0:50010
0.0.0.0:50075
10.192.25.199:8093
0.0.0.0:8670
結果は予想通りです。
質問 the default delimiter is only space for awk?
はあいまいですが、あなたが尋ねるかもしれない両方の質問に答えようと思います.
FS
のデフォルト値 変数 (awk がレコードを読み取るときにレコードをフィールドに分割する方法を awk に指示するフィールド区切り記号を保持する) は、単一の空白文字です。
awk がレコードをフィールドに分割するために使用するのは「フィールド セパレーター」です。これは、フィールド セパレーターが単一の空白文字である場合にのみ適用される追加機能を備えた正規表現です。その追加機能は次のとおりです。
<オール>[ ]
と指定する必要があります 正規表現でできるようなスタンドアロンのリテラル空白文字の代わりに。
入力が読み取られるときにレコードをフィールドに分割するために使用されるフィールドセパレーターに加えて、それらは他のいくつかのコンテキストで使用されます。 split()
の 3 番目の引数 したがって、どのコンテキストが文字列、正規表現、またはフィールドセップを必要とするかを知っておくことが重要であり、man ページでそれぞれが明確に指定されています。
とりわけ、上記はこれを説明しています:
$ echo ' a b c ' | awk '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
5: <> <a> <b>
最初の 2 つが同じ出力を生成するのに最後の 2 つが異なる理由がわからない場合は、質問してください。