У меня есть файл .csv, который имеет некоторые значения, отформатированные как абзацы с разрывами строк или иногда с маркерами.

"STAT","ID","DESC"
"UPD", "1", "Updated"
"CHG", "2", "Changed"
"UPD", "3", "Updated.
Might have to update again"
"UPD", "4", "Updated.

 - once 
 - twice
 - thrice
"
"DEL", "5", "unknown"
"DEL", "6", "Deleted
Need to restore"

Мне нужно посчитать количество записей, используемых awk, как показано ниже, так как я знал, что 2-й столбец является уникальным идентификатором, но возвращает больше, чем у меня. Над текстом, конечно же, есть пустышка, так как мне не разрешено делиться оригиналом, но я старался размышлять как можно ближе.

 awk  '{print $2}' FS=","  sample.csv | wc -l 

Я даже распечатал первый столбец, используя awk '{print $ 1}', чтобы проверить только значения первого столбца, но вывод показывает начальные части новой строки в абзацах.

Пожалуйста, дайте мне знать, если потребуется дополнительная информация, и я обновлю вопрос.

2 ответа2

0

Способ сделать это с помощью awk

awk -v RS=$'"\n"' 'END {print NR}' sample.csv
  • RS=$'"\n"' устанавливает S eparator R ecord (который является новой строки по умолчанию) в три-символьной строки " новой "  Этот синтаксис может работать только в bash .  Это приведет к тому, что ваш файл будет разложен на следующие записи:

    1: "STAT","ID","DESC

    2: UPD", "1", "Updated

    3: CHG", "2", "Changed

    4: UPD", "3", "Updated.
        Might have to update again

    5: UPD", "4", "Updated.
       
        - once
        - twice
        - thrice
       

    6: DEL", "5", "unknown

    7: DEL", "6", "Deleted
        Need to restore"

    Это предполагает, что в файле нет завершающих пробелов. 

  • 'END {print NR}' читает файл до конца, а затем печатает номер записи - другими словами, количество записей.

Обычно считается, что текстовые файлы состоят из последовательности строк, разделенных символами новой строки или последовательностями символов.  И, как правило, «запись» в текстовом файле считается одной строкой.  Но awk позволяет вам указать разделитель записей, отличный от новой строки.  Поскольку строка quote-newline-quote появляется между каждой парой последовательных записей в вашем файле, указав ее в качестве разделителя записей, вы разбиваете файл (почти) на нужные вам записи.

Но разделитель записей похож на стену между двумя комнатами - он не является частью ни одной из них.  При обычной обработке awk вы видите записи, представляющие собой строки без символов новой строки - они удаляются.  Аналогично, в моем ответе последовательности quote-newline-quote удалены.  Но, поскольку до первой записи или после последней нет разделителя записей, самые первые и самые последние символы кавычек не удаляются.

Если вы хотите обработать файл по одной записи за раз, это решение может оказаться недостаточно хорошим, поскольку первая и последняя записи обрабатываются по-разному.  Я (в некоторой степени) согласен с рекомендацией Гленна о том, что для любой серьезной работы вы должны использовать «правильный анализатор CSV».

0

Я настоятельно рекомендую выбирать язык с правильным парсером CSV. Мне нравится рубин, это очень лаконично:

ruby -rcsv -e 'a = CSV.read(ARGV[0], :col_sep => ", "); puts a.length' file
7

Мне пришлось изменить разделители столбцов в строке заголовка, чтобы добавить пробелы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .