ファイル内の指定された日付よりも新しい行を削除します


8

指定された日付よりも新しい行を削除する方法に行き詰まっています。これはファイルの内容の抜粋です。

buildsave.txt

647919 2013/11/30
647946 2013/11/30
647955 2013/12/01
648266 2013/12/03
648267 2013/12/03
648674 2013/12/04

2013/12/03より新しい行のみを残して削除したい

647919 2013/11/30
647946 2013/11/30
647955 2013/12/01

これはどのようにbashを介して実行できますか?

回答:


4

システムにdateコマンドのGNUバージョンが含まれている場合、それを使用して(<br>存在する場合は、末尾のを取り除いた後)日付フィールドをseconds-since-epochに変換し、同じ形式(bashなど)でカットオフ日付と直接比較できます。

testsecs=$(date +%s --date="2013/12/03")
while IFS= read -r line; do
  read -r x d <<< "$line" 
  if (( $(date +%s --date="${d%<br>}") < $testsecs )); then
    printf '%s\n' "$line"
  fi
done < buildsave.txt

[これはインプレース削除を実行しないことに注意してください-結果を一時ファイルに保存して名前を変更する必要があります。]


あなたは私を頭痛から救った。これがまさに私が探していたものです!
Jason G

おい!これらの日付は辞書順および年代順に同じように並べ替えられます。それらを整数に変換して5つのコマンドを実行する必要はなく、1行に1つの一時ファイルと2つのパイプを作成します。
ステファンChazelas

9

これらの日付は辞書順および年代順で同じように並べ替えられるため、字句比較を行うだけです。

awk '$2 < "2013/12/03"'

2

私は仮定<br>の終わりに、あなたの問題のdate列がために、不要なものです。いずれの場合も、存在する場合は簡単に削除できます。ただし、主要部分に到達すると、使用しようとしていることを達成できます。

sort -k 2n filename.txt

ここで、上記のコマンドは出力をソートされた方法で提供します。今、以下のコマンドはあなたが探しているものを与えるはずです。

sort -k 2n filename.txt | awk '/2013\/12\/03/ {exit} {print}' 

説明

sortコマンドは基本的に、日付である2番目の列に基づいてファイルをソートします。したがって、入力ファイルにはすべてのデータがデフォルトでソートされているため、コマンドが機能するかどうかをテストするように入力ファイルを変更しました。その後awk、特定の一致が見つかるまで、コマンドはすべての行を出力します。

テスト中

cat filename.txt

647919 2014/01/01
647946 2012/11/30
647955 2011/01/04
648266 2013/12/03
648267 2013/12/03
648674 2013/12/04

今、sort -k 2n filename.txt出力は、

647955 2011/01/04
647946 2012/11/30
648266 2013/12/03
648267 2013/12/03
648674 2013/12/04
647919 2014/01/01

これで、ファイルが2番目の列でソートされたことに満足しました。さて、値を選択する点で最大特定の日付、

sort -k 2n filename.txt | awk '/2013\/12\/03/ {exit} {print}' 

上記の例では、までのすべての値を取得しています2013/12/03。出力は、

647955 2011/01/04
647946 2012/11/30

いいえ、<br>ファイルの一部です

この場合は、以下のようにコマンドを少し調整します。

awk '{print $1, substr($2, 1, length($2)-4)}' filename.txt | 
sort -k 2n filename.txt | awk '/2013\/12\/03/ {exit} {print}' 

したがって<br>、2番目の列からすべてのタグを削除し、上記のコマンドをパイプ処理しています。

参考文献

https://unix.stackexchange.com/a/11323/47538

https://unix.stackexchange.com/a/83069/47538


ご入力ありがとうございます。これは確かに非常に機能しますが、特定の日付がファイルに存在しない場合、終了する条件は常に機能するとは限りません。
Jason G

いいえ、物を読みやすくするためだけにbrタグが追加されているようです。それらは最初のリビジョンでは見ることができません
Braiam

-1

あなたが与えた1つの日付のための迅速で汚い解決策、この日付より後の日付に一致するsedを含むすべての行を削除するだけです:

sed -i "" "#[0-9]* 2013/12/0[4-9]#d" testfile.txt
sed -i "" "#[0-9]* 2013/12/[123][0-9]#d" testfile.txt
sed -i "" "#[0-9]* 2014/[0-9][0-9]/[0-3][0-9]#d" testfile.txt

-i ""はファイル内で直接置き換えられ、バックアップは作成されませんが、-i ""なしで3つのsedコマンドすべてにtestfileをパイプすることもできます。

システム(LinuxまたはMac)によっては、-iの後に ""を省略できます。場合によっては、正規表現に-eパラメータが必要です。お奨めの方法を試してみてください。

sedの詳細に関する関連する質問:https : //stackoverflow.com/questions/5410757/


#コメントコマンドなsedので、何もしません。sed '\#patter#d'とは異なるRE区切り文字が必要な場合に使用します/[0-9]*一部はせずに冗長である^アンカー。複数の式を渡したい場合に-eのみ必要です。linuxはカーネル、macはコンピューターブランド、どれもとは関係ありませんsed。違いは、GNU sedとFreeBSD sed(OS / X(一部のMacで見られる)が継承)の間です。
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.