Последняя строка неверна при разбиении файла на awk

У меня есть файл main.txt с данными, который выглядит так:

 20130826,aaaaaaaaaaaaaa,bbbbbbb 20130826,sdfasdfasdfas,sdfasdfasd 20130826,dfasdfas,asdf2323 ... 20130827,sfasdfasdfasd,sdfasdfwea 

Я использовал следующий фрагмент awk для разделения main.csv на меньшие файлы по дате.

 cat test01 | stdbuf -oL -eL awk -F',' '{print $2","$3 >> "data"$1".csv"; fflush()}' 

и я обнаружил, что для разбитого файла data20130826.csv последняя строка неполна,

 ... 20130826,dfasdfas,asdf2323 2013082 

на самом деле последние несколько строк (10 или около того) даты 20130826 отсутствуют, они также не находятся в data20130827.csv. Я попытался отключить буферизацию, как в приведенной выше строке, но, похоже, это не помогает. Я уверен, что основной файл в порядке. Что случилось? Я использую GNU Awk 4.0.1.

  • Форматировать вывод на определенную длину строки
  • Печать только N-й строки перед каждой строкой, соответствующей шаблону
  • Удалять конечные пробелы только из первого поля
  • Удалить строку перед пробелом
  • Условный блок с условным выражением (если)
  • среднее количество определенных строк в файле и вывод в файле с разделителями табуляции
  • лучший способ разделить огромные файлы на основе поля, когда awk слишком медленный
  • Синтаксическая ошибка удаления повторяющихся строк через файл awk '! X ++
  • 2 Solutions collect form web for “Последняя строка неверна при разбиении файла на awk”

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

    Итак, сколько разных дат во входном файле? Thats, сколько открытых файлов у вас будет:

     cut -d"," -f1 test01 | sort | uniq | wc -l 

    – если это много (сотни), то см. мое второе предложение относительно закрытия файлов по ходу дела.

    Два предложения:
    1. Вы уверены, что данные являются простым текстом без каких-либо скрытых символов, таких как обратные пространства, а также имеют нормальные окончания строки UNIX? Можете ли вы выровнять строки с префиксом «20130826», чтобы увидеть, что они выглядят нормальными и действительно являются отдельными строками, т.е.

     cat test01 | grep "^20130826" - and also run cat test01 | grep -c "^20130826" 

    – подтвердить, что количество строк grep соответствует тому, что находится в выходном файле (или нет)

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

     cat test01 | awk -F"," '{prevfile=ofile; ofile=sprintf("data%s.csv",$1); if (NR > 1 && ofile != prevfile) close(prevfile); print $2","$3 >> ofile}' 

    Этот код по-прежнему будет работать, если ваш файл не сортируется по дате, но будет чаще открывать и закрывать файлы. В этом случае просто измените «cat test01» на «sort test01» в начале команды.

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

    Также, когда вы добавляете эти файлы, убедитесь, что они не содержат никаких данных перед запуском команды. Легко забыть, когда что-то не работает …

    Пытаться:

     $ cat test01 | stdbuf -oL -eL awk -F',' '{print $2","$3 >> "data"$1".csv"; fflush("")}' 

    В gawk 4.0.1 , вызывающий fflush () без каких-либо аргументов, только flush stdout. Вам нужно вызвать fflush() с пустой строкой "" чтобы awk очистил все открытые выходные файлы и трубы.

    С gawk 4.0.2 и более поздними gawk 4.0.2 , если аргументов нет, или аргумент для fflush() является пустой строкой "" , тогда awk очищает буферы для всех открытых выходных файлов и труб.

    Interesting Posts

    Как я могу получить обратную связь от хранителя дерева для патчей, отправленных на lkml?

    Установка Linux для умственно отсталых

    Как избавиться от фиктивного интерфейса?

    Сценарирование машинного текста

    Введите символы из фонетических символов с клавиатуры

    Как заменить этот шаблон на новую строку внутри?

    удалять дубликаты файлов в 2 каталогах

    Bash: как распечатать дополнительный столбец, соответствующий IP-адресу для имени

    Как не проходить через туннель openvpn для определенного порта

    Fedora 8 в последнее время очень медленно замедляется с частыми заморозками

    ln -s $ SOURCE / * except – с помощью find?

    Помощь в исправлении систем RHEL 6.x с воздушным потоком на удаленных объектах

    Общий препроцессор добавляет дополнительные пробелы

    Почему эта работа crontab не работает

    Создание программного обеспечения для Linux, созданного с использованием многострочной

    Linux и Unix - лучшая ОС в мире.