删除文件中比给定日期新的行


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做到这一点?

Answers:


4

如果您的系统包含该date命令的GNU版本,则可以使用该命令将date字段(剥离尾部<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

[请注意,这不会执行就地删​​除-您需要将结果保存到临时文件中并重命名。]


先生您让我头疼。这正是我想要的!
詹森·G

y!这些日期按字典顺序和时间顺序排序,无需将它们转换为整数并运行5个命令,只需创建一个临时文件和每行两个管道!
斯特凡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命令基本上根据第二列(即日期)对文件进行排序。因此,我修改了您的输入文件以测试该命令是否有效,因为该输入文件默认情况下对所有数据进行了排序。之后,该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

现在,我们对文件在第二列上排序感到满意。现在,选择值UPTO特定日期,

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

在上面的示例中,我得到了所有值upto 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>从第二列中删除所有标签,然后管道传输上述命令。

参考文献

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

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


谢谢您的意见。这确实非常有效,但是,当文件中不存在特定日期时,退出条件并不总是有效。
詹森·G

不,似乎只是为了使事物可读而添加了br标签。在第一次修订中看不到它们
Braiam 2014年

-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命令通过管道传递测试文件。

根据您的系统(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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.