2番目の列に日付を含むデータファイルがあります。
# cat datafile
-;20210106;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
...
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
-;20210219;-;-;-;
-;20210221;-;-;*20210219*;
ハイフン-
はランダムなテキストデータを表し、ドット...
はより多くのデータ行を表し、*は同じ列のランダムテキストを表します。私が望むのは、2番目の列間の20210112
データに基づいていることです20210219
。
sed/grep
どちらも他の列の同様のパターンを見つけるので、これを避けたいと思います。
# sed -n '/20210112/,/20210219/p' datafile
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
...
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
-;20210219;-;-;-;
-;20210221;-;-;*20210219*;
また、関連していない他の行の他のテキストとも一致します。したがって、AWKはより良い候補だと思いますが、awkは最初のパターンの最初の一致と2番目のパターンの最初の一致の間にのみ印刷することがわかりました。
# awk -F';' '$2 ~ /20210112/,$2 ~ /20210219/' datafile
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
...
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
しかし、すべての行を2番目のモードの最後のゲームにインポートしたいと思います。
予想される
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
...
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
-;20210219;-;-;-;
答え1
これが私がする方法です:
BEGIN {FS = ";"}
$2 == 20210112 {capture = 1}
capture == 1 {buffer = buffer $0 "\n"}
$2 == 20210219 {printf ("%s", buffer); buffer = ""}
最初のパターンが最初に表示されることを確認したら、バッファに行を挿入し始めます。 2番目のパターンが現れるたびにバッファを印刷し、バッファを空の文字列にリセットします。
答え2
その行を無視し...
てすべての日付が$ 2の昇順であると仮定すると(例に示すように)、必要なものは次のとおりです。
$ awk -F';' '(20210112 <= $2) && ($2 <= 20210219)' file
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
-;20210219;-;-;-;
または範囲を超えると終了するので、より効率的です。
$ awk -F';' '20210112 <= $2{f=1} $2 > 20210219{exit} f' file
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
...
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
-;20210219;-;-;-;
上記の内容も、入力に終了日がない場合は開始日からファイルの終わりまで印刷し、開始日がない場合はファイルより大きい最初の日付から印刷すると仮定します。開始日から終了日までなど
答え3
いつ決める最後パターンの発生を確認するには、前の行を覚えてパターンが表示されなくなったと確信したときにのみ出力する必要があることがよくあります。〜する見える。
この操作を手動で実行する必要がないようにするには、ファイルの先頭を切り取り、ファイルの新しい先頭を切り取り、元に戻すことができます。
awk -F\; '$2 == 20210112,0' | tac | awk -F\; '$2 == 20210219,0' | tac
答え4
でこれを行うことができ、awk
少し複雑なアプローチが必要です。==
代わりに使用することに注意してください~
。これは、一致フィールドが部分文字列を含む、または20210112
部分20210219
文字列である状況(例20210219123
:)を避けるためです。
$ awk -F';' '$2==20210112{a=1}; $2==20210219 && a{b=1} a && b && $2!=20210219{exit}; a ' datafile
-;20210112;-;-;-;
-;20210112;-;-;-;
-;20210112;-;-;-;
...
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210217;-;-;-;
-;20210219;-;-;-;
-;20210219;-;-;-;
またはより詳細ですが、理解しやすいです。
$ awk -F';' '{
if($2==20210112){ a=1 }
if($2==20210219 && a){ b=1 }
if(a && b && $2!=20210219){ exit };
if(a){ print }
}' datafile
または数値比較を実行してみてください。
awk -F';' '$2>=20210112 && $2<=20210219' datafile
しかしsed
、必要に応じて、次のものを引き続き使用できます。 2番目のフィールドでのみ一致するようにパターンを固定するだけです。
$ sed -n '/^[^;]*;20210112/,/^[^;]*;20210219/p' datafile
この場合、最初の一致で停止するので役に立ちませんが、少なくとも他のフィールドでは一致しません。