Unixスクリプトは、同じキーレコードと比較してデータを処理します。

Unixスクリプトは、同じキーレコードと比較してデータを処理します。

私が経験している問題は、入力ファイルに有効な日付と終了日の履歴があることです。最初の6つのフィールドはキー(12345A)です。同じキーである1日を使用して、次のレコードの有効な(8位)日付に基づいて終了日(18位)を更新する必要があります。有効日が最新のレコードの場合、終了日は9999-12-31に保たれる必要があります。以下は入力と出力の期待です。誰でも私を助けることができますか?テーブルがアンロードされたときにファイルAをインポートし、終了日がこのように入力されると予想するインターフェイスアプリケーションに後で送信する必要があります。テーブル自体の終了日を変更することはできません。これはアンロード時に変更しようとしています。理由ファイル。

データ区切り記号/区切り文字はなく、キーの長さは常に同じままです。

入力ファイル):

12345A22021-01-259999-12-31
12345A12021-01-019999-12-31
12345B32021-02-159999-12-31
67899C12021-03-019999-12-31
67899D32021-05-249999-12-31
67899D22021-04-029999-12-31

出力(ファイルB):

12345A22021-01-259999-12-31
12345A12021-01-012021-01-24
12345B32021-02-159999-12-31
67899C12021-03-019999-12-31
67899D32021-05-249999-12-31
67899D22021-04-022021-05-23

ベストアンサー1

sed同じIDを持つ古いレコードの有効な日付が終了日と見なされる限り、次の基準とパターンを使用してN;P;Dこれを実行できます。

sed '$!N;s/^\(.\{6\}\)\(.\)\(.\{10\}\)\(.*\n\1.\{11\}\).*/\1\2\3\4\3/;P;D'

ただし、日付を変更する必要がある場合は、GNUなどのカレンダーを理解するユーティリティが必要ですdate

date -d "2021-09-08 yesterday" +"%Y-%m-%d"

2021-09-07私は多くのバージョンがdateこれを行うと思います。ただし、現在のGNUdateとGNUでは、sed次のように動作します。

sed -nE 'G
  s/^(.{6})(.{11}).*\n\1.(.{10}).*/\1\2\3/p
  s/\n.*//p
  s/^(.{7})(.{10})/echo \1$(date -d "\2 yesterday" +"%Y-%m-%d")/e
  h' fileA > fileB

説明しましょう。

  • nデフォルト出力を抑制するオプションとE正規表現を拡張するオプションを使用します(読みやすくするため)。
  • G前の行を保持する予定のスペースを追加し、適切な日付を追加します(以下を参照)。
  • s/^(.{6})(.{11}).*\n\1.(.{10})/\1\2\3/p同じID(したがって逆参照\1)がある場合は、現在の行の日付を予約済みスペースの調整日に置き換えてp印刷します。
  • s/\n.*//p置換が発生しない場合は、追加の行を削除してp印刷します。
  • s/^(.{7})(.{10})/echo \1$(date -d "\2 yesterday" +"%Y-%m-%d")/eGNUsedexecuteフラグを利用して、日付をdateユーティリティに送信して日付を減らします。
  • hスペースを節約するには、変更された行を保存してください。

おすすめ記事