一部の日付が無効な2つの日付の間のファイルのサブセット

一部の日付が無効な2つの日付の間のファイルのサブセット

私はいくつかの同様の問題に直面しましたが、解決策が失敗したようです。私はファイルにタイムスタンプでフィルタリングする試みを台無しにするジャンクデータがあったからだと思います。

以下はサンプルファイルです。

2020-12-12 12:10:00,3,4,2
2020-12-12 12:11:00,4,3,2
2020-12-12 12:12:00,4,3,2
2020-12-12 12:13:00,4,3,2
20-12-12 12:14:00,4,3,2
4,3,2
2020-12-12 12:16:00,4,3,1
-12-12 12:17:00,4,3,2
2020-12-12 12:18:00,5,3,2

このファイルをフィルタリングし、有効なタイムスタンプのみを含む新しいファイルを作成したいと思います(各行は有効なタイムスタンプで始まる必要があります)。

BegDate="2020-12-12 12:11:00"
EndDate="2020-12-12 12:16:00"

私はsedを試してみました。

TimeWindow=$(sed -rne '/'$BegDate'/,/'$EndDate'/p' $MyFile)
echo $TimeWindow > NewFile.csv

そしてうん

awk -v from=$BegTime -v to=$EndTime '$1>=from && $1<=to' "$MyFile" > "NewFile.csv"

しかし、両方とも失敗

「NewFile.csv」の期待される結果は次のとおりです。

2020-12-12 12:11:00,4,3,2
2020-12-12 12:12:00,4,3,2
2020-12-12 12:13:00,4,3,2
2020-12-12 12:16:00,4,3,1

答え1

awk最初のフィールドが有効な日付形式に準拠していることを確認して、アプローチを改善することもできます。

LC_ALL=C awk -F, -v from="$BegTime" -v to="$EndTime" '
  BEGIN {valid = "^" from "$"; gsub("[0-9]", "[0-9]", valid)}
  $1 ~ valid && $1 >= from && $1 <= to'

日付検証のための上記の正規表現は、数値を(Cロケールと同じ)$BegTimeに置き換え、開始と終了のアンカーを開始と終了の両方でアンカーに追加することによって作成されます。[0-9][0123456789]^$

無効な日付(例:9999-99-99 99:99:99または2022-02-29 00:00:00)も除外したい場合は、正規表現を最適化できます。

すべてのシェルパラメータ拡張を引用する必要があります。コードが次の例のいずれかとどのように一致するかを確認してください。bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク)。また、あなたの質問とBegTimeの間の違いを書き留めてください。BegDate

関連情報