У меня есть папка с файлами 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
Но это не заботится о моей операции в "порядке по возрастанию даты".
Какие-либо предложения о том, как я мог бы выполнить это? Я хотел бы сделать этот удар использования.
Можно сделать это путем объединения нескольких общих инструментов:
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
. Не уверенный, если некоторые специальные символы в именах файлов могли бы повредить материал (пробелы должны, вероятно, быть безопасными, новые строки, конечно, повредят его).