Выходной файл намного больше, чем входные файлы после cat + grep - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть 18 CSV-файлов, все между 1 МБ и 14 МБ.Сумма всех файлов составляет 64 МБ.Я хочу создать новый CSV-файл, который содержит подмножество этих файлов - только строки с шаблоном «Hello» (или «HELLO», или «hello» ...).Вот что я делаю

   cat *.csv | head -n 1 > new.csv   # I want to create a header first
   cat *.csv | grep -i "hello" >> new.csv

Я использую Debian на WSL.Выходной файл намного, намного больше, чем исходные 64 МБ (я остановил процесс через 1+ часа, а файл был более 300 ГБ).

Как подмножество текстового файла может быть больше исходногофайлы?Это как-то связано с WSL?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Это не проблема ОС.Когда вы перенаправляете вывод в new.csv, оболочка сначала создает этот файл, прежде чем вычисляется выражение glob *.csv.Это означает, что расширение *.csv также будет включать new.csv.Это похоже на основную причину рекурсивной проблемы grep, с которой вы сталкиваетесь.

Вы читаете все файлы дважды, что не является необходимым.Вы можете сделать свою работу намного проще и эффективнее с помощью одной команды awk:

awk 'NR==1 {print} tolower($0) ~ /hello/ {print}' *.csv > csv.new
mv csv.new new.csv
  • , поскольку выходной файл называется csv.new, он не будет мешать работе с глобусом *.csv
  • NR==1 берет первую строку (заголовок) из самого первого файла

Команда awk может быть записана более кратко как:

awk 'NR==1 || tolower($0) ~ /hello/' *.csv > csv.new
0 голосов
/ 20 февраля 2019

Вы используете *.csv и перенаправляете вывод на new.csv, который попадает под *.csv, что вызывает рекурсию в результате поиска grep.возможно, вы можете попробовать,

grep -i hello *.csv --exclude="new.csv"  >> new.csv
...