我有数百万条记录文件,其中包含“目录、文件名、权限、组和所有者、大小、上次访问日期、上次修改日期、上次更改日期)。我需要获取最后的行(文件)访问日期和上次修改日期小于或等于 2012 年。
例子:
23 8 drwx------ 16 userid grpid 2048 2009-06-25 20:42 2011-03-03 17:27 2011-03-03 17:27 /path/dir
66738 8 drwx--S--- 3 userid grpid 1024 2010-03-05 11:49 2015-07-07 17:48 2010-03-05 11:49 /path/dir/dir2
90354 8 -rw-r----- 1 userid grpid 65536 2016-05-25 15:28 2008-05-22 12:00 2014-03-05 16:00 /path/dir/dir2/file1
89743 8 -rw-r----- 1 userid grpid 65536 2016-05-25 15:28 2008-05-22 12:00 2010-03-05 16:00 /path/dir/dir2/file2
答案1
最短的 awk 代码是:
awk '$3 ~ /^-/ && $8 < "2013" && $10 < "2013"' file
这对通过测试的记录使用默认操作(打印)。
它还利用了词法排序,其中:
"2012-12-31" < "2013"
是真的并且"2013-01-01" < "2013"
是假的
答案2
修改示例输入以在输出中获得一个匹配行
$ cat ip.txt
23 8 drwx------ 16 userid grpid 2048 2009-06-25 20:42 2011-03-03 17:27 2011-03-03 17:27 /path/dir
66738 8 -rwx--S--- 3 userid grpid 1024 2010-03-05 11:49 2011-07-07 17:48 2010-03-05 11:49 /path/dir/dir2
90354 8 -rw-r----- 1 userid grpid 65536 2016-05-25 15:28 2008-05-22 12:00 2014-03-05 16:00 /path/dir/dir2/file1
89743 8 -rw-r----- 1 userid grpid 65536 2016-05-25 15:28 2008-05-22 12:00 2010-03-05 16:00 /path/dir/dir2/file2
$ grep -P '^(\S+\s+){2}-(?1){5}(\d\d(0\d|1[0-2]))(?1){2}(?2)' ip.txt
66738 8 -rwx--S--- 3 userid grpid 1024 2010-03-05 11:49 2011-07-07 17:48 2010-03-05 11:49 /path/dir/dir2
(\S+\s+)
非空格文本后跟空格。{5}
或者{2}
告诉它重复很多次\d\d(0\d|1[0-2])
年份2012
或之前(假设年份的前两位数字不超过20
)(?1)
指的是(\S+\s+)
并且(?2)
指的是(\d\d(0\d|1[0-2]))
perl
解决方案类似于格伦的回答
$ perl -ae 'print if $F[2] =~ /^-/ && $F[7] < 2013 && $F[9] < 2013' ip.txt
66738 8 -rwx--S--- 3 userid grpid 1024 2010-03-05 11:49 2011-07-07 17:48 2010-03-05 11:49 /path/dir/dir2
添加> output.txt
到命令末尾以将结果保存到另一个文件
答案3
AWK 和 Operator 在这里帮助了我。由于我只需要文件而不是目录,所以我过滤了文件以查找以“-”开头的权限列。
猫 文件名 | awk '($3 ~ /^-/)'
然后减少日期格式来表示年份,因为我只关心使用 sed 。
猫 文件名 | awk '($3 ~ /^-/)' | sed 's/-[0-9][0-9]//g'
现在 awk AND 运算符比较了两列,我得到了我期望的输出。
猫 文件名 | awk '($3 ~ /^-/)' | sed 's/-[0-9][0-9]//g' | sed 's/-[0-9][0-9]//g' | awk ' $8 < 2013 && $10 < 2013 ' > files_older_2012
谢谢大家。这是我去过的最好的地方。