按日期文件名的顺序从文件中提取行数

按日期文件名的顺序从文件中提取行数

我有一个文件夹,其中包含 csv 文件的文件名是日期,即:January-01-2018.csv,,January-02-2018.csv...,April-30-2018.csv

最好使用 Bash,我想从每个 csv 文件中提取行数,但按日期顺序进行。即,我希望提取行数,然后January-01-2018.csv...January-02-2018.csv然后April-30-2018.csv等等。

目前,我所拥有的只有:

for filename in $(ls *.csv); do cat $filename | wc -l >> by_day.dat; done

但这确实不是按照“日期升序”顺序处理我的操作。

关于如何实现这一点,有什么建议吗?我想使用 bash 来做到这一点。

答案1

您可以通过组合一些常用工具来实现此目的:

  • find列出所有 .csv 文件(无序)并为每个文件执行一条命令
  • basename.csv从路径中提取不带扩展名的文件名
  • date解释文件名中的日期规范并将其转换为易于排序的数字,例如自 1970 年以来的秒数。
  • echo为每个文件在一行中打印计算出的数字和实际文件路径
  • sort根据转换后的日期数字对文件路径进行排序
  • cut从组合列表中再次仅提取文件路径
  • xargs cat通过将所有文件名按顺序传递给命令来构造一个命令cat以将它们连接起来。

如果我们要处理的所有文件都位于名为的文件夹中,则完整的行如下所示datecsv

$ find datecsv/ -name '*.csv' -exec bash -c 'echo "$(date -d "$(basename -s.csv "{}")" +%s) {}"' \; | sort -n | cut -d' ' -f2- | xargs cat
2018,1,1,aaa
2018,1,1,bbb
2018,1,2,ccc
2018,1,2,ddd
2018,4,30,eee
2018,4,30,fff

产生上述输出的示例文件如下:

$ cat datecsv/April-30-2018.csv
2018,4,30,eee
2018,4,30,fff
$ cat datecsv/January-01-2018.csv
2018,1,1,aaa
2018,1,1,bbb
$ cat datecsv/January-02-2018.csv
2018,1,2,ccc
2018,1,2,ddd

由于您只想要每个文件的行号,因此命令如下:

$ find datecsv/ -name '*.csv' -exec bash -c 'echo "$(date -d "$(basename -s.csv "{}")" +%s) {}"' \; | sort -n | cut -d' ' -f2- | xargs -n1 wc -l
2 datecsv/January-01-2018.csv
2 datecsv/January-02-2018.csv
2 datecsv/April-30-2018.csv

唯一的变化是最后一部分,我们使用xargs -n1 wc -l而不是xargs cat上面的。

一些说明:上述方法依赖于文件名是date可以解析的格式。您提供的示例名称就是这种情况,但如果格式发生变化,它可能会中断。它还要求文件名以小写字母结尾.csv。不确定文件名中的某些特殊字符是否会破坏某些内容(空格应该是安全的,换行符肯定会破坏它)。

相关内容