私が経験している問題は、入力ファイルに有効な日付と終了日の履歴があることです。最初の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")/e
GNUsed
のe
xecuteフラグを利用して、日付をdate
ユーティリティに送信して日付を減らします。h
スペースを節約するには、変更された行を保存してください。