で区切られた行でフィールドを印刷したいと思います|~^
。いくつかの方法を試しましたが、印刷フィールドを操作できませんでしたawk
。以下は参考用ファイルの内容です。
入力する
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-05|~^10.00
R|~^abc|~^2019-03-05|~^20.00
R|~^abc|~^2019-03-05|~^30.00
R|~^abc|~^2019-03-06|~^100.00
R|~^abc|~^2019-03-06|~^15.00
R|~^abc|~^2019-03-06|~^10.00
T|~^20200425|~^6|~^185.00
|~^
区切り文字ベースを使用してフィールドを区切る必要がありますawk
。頑張った
cat input |grep "^T"|awk -F '|~^' '{print $2}'
しかし、nullを返します。
どんな提案がありますか?
答え1
awk
あなたが直面する問題は、(GNU)マンページ[1]の次の説明に関連しているようです。
FSが単一文字の場合、フィールドはその文字で区切られます。 FSが空の文字列の場合、個々の文字は別々のフィールドになります。それ以外の場合、FSは完全な正規表現でなければなりません。。
フィールド区切りパターンには正規表現で特別な意味を持つ文字(the|
とthe ^
)が含まれているため、その文字を正しくエスケープする必要があります。awk
変数がどのように解釈されるか(文字列リテラル解析)二重)、次のように指定する必要があります。二重バックスラッシュ、良い
awk -F '\\|~\\^' '{print $2}' input.txt
あなたの例の結果出力は次のとおりです。
20200425
abc
abc
abc
abc
abc
abc
20200425
T
次から始まる行のみを考慮するには
awk -F '\\|~\\^' '/^T/ {print $2}' input.txt
または、特定のフィールド(ここでは最初のフィールド)の値が次のような行を選択するだけですT
。
awk -F '\\|~\\^' '$1=="T" {print $2}' input.txt
どちらの場合も、例の結果
20200425
一般的に、およびを使用する必要はほとんどawk
ありませんgrep
。sed
また、これらのツールはすべてファイルに直接アクセスできるため、cat
処理するためにテキストを提供する必要はありません。
[1]:(関連していない)注:「空の文字列」を含む部分は、すべてのAwkバリアントでは機能しません。 GNU Awk マニュアルには次の内容が記載されています。「これは一般的な拡張です。POSIX標準ではこれを指定しません。」
答え2
例を見つけましたここ少し修正されました。
別の方法は、別の区切り文字に置き換えて使用することです。
cat infile |sed "s/|~^/,/g"
H,20200425,abcd,sum
R,abc,2019-03-05,10.00
R,abc,2019-03-05,20.00
R,abc,2019-03-05,30.00
R,abc,2019-03-06,100.00
R,abc,2019-03-06,15.00
R,abc,2019-03-06,10.00
T,20200425,6,185.00
$ cat infile |sed "s/|~^/,/g" | cut -d',' -f2-3
20200425,abcd
abc,2019-03-05
abc,2019-03-05
abc,2019-03-05
abc,2019-03-06
abc,2019-03-06
abc,2019-03-06
20200425,6
2
after は-f
開始列と3
終了列です。