Число извлечения, если строки из файла в порядке имени файла даты

У меня есть папка с файлами 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

Но это не заботится о моей операции в "порядке по возрастанию даты".

Какие-либо предложения о том, как я мог бы выполнить это? Я хотел бы сделать этот удар использования.

2
задан 2 May 2018 в 15:58

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. Не уверенный, если некоторые специальные символы в именах файлов могли бы повредить материал (пробелы должны, вероятно, быть безопасными, новые строки, конечно, повредят его).

3
ответ дан 2 December 2019 в 02:43

Другие вопросы по тегам:

Похожие вопросы: