Сохраняйте только строки, содержащие точное количество разделителей

У меня огромный файл csv с 10 полями, разделенными запятыми. К сожалению, некоторые строки неверны и не содержат ровно 10 запятых (что вызывает некоторые проблемы, когда я хочу прочитать файл в R). Как я могу отфильтровать только строки, содержащие ровно 10 запятых?

7 Solutions collect form web for “Сохраняйте только строки, содержащие точное количество разделителей”

Другой POSIX:

 awk -F , 'NF == 11' <file 

Если строка содержит 10 запятых, то в этой строке будет 11 полей. Поэтому мы просто используем awk , как полевой разделитель. Если число полей равно 11, условие NF == 11 истинно, awk затем выполняет действие по умолчанию print $0 .

Использование egrep (или grep -E в POSIX):

 egrep "^([^,]*,){10}[^,]*$" file.csv 

Это отфильтровывает все, что не содержит 10 запятых: оно соответствует полным строкам ( ^ в начале и $ в конце), содержащим ровно десять повторений ( {10} ) последовательности «любое количество символов, кроме«, », за которым следует single ',' "( ([^,]*,) ), за которым следует любое количество символов, кроме ',' ( [^,]* ).

Вы также можете использовать параметр -x для удаления якорей:

 grep -xE "([^,]*,){10}[^,]*" file.csv 

Это менее эффективно, чем решение awk от cuonglm ; последний, как правило, в шесть раз быстрее в моей системе для линий с 10 запятыми. Более длинные линии вызовут огромные спады.

 sed -ne's/,//11;t' -e's/,/&/10p' <in >out 

Это первое разветвляет любую строку с 11 или более запятыми, а затем печатает то, что остается только теми, которые соответствуют 10 запятым.

Видимо, я ответил на это раньше … Вот я-плагиат из вопроса, ищущего ровно 4 появления какой-то картины:

Вы можете настроить [num] -е появление шаблона командой sed s/// ubstitution, просто добавив [num] к команде. Когда вы хотите успешную подстановку и не указываете метку target : label, t est отходит от скрипта. Это означает, что все, что вам нужно сделать, это проверить для s///5 или более запятых, а затем распечатать то, что осталось.

Или, по крайней мере, обрабатывает линии, которые превышают максимум 4. Очевидно, у вас также есть минимальное требование. К счастью, это так же просто:

 sed -ne 's|,||5;t' -e 's||,|4p' 

… просто замените 4-е появление на линии с самим собой и привяжите ваш p rint к флагам s/// ubstitution. Поскольку любые строки, соответствующие , 5 или более раз, уже были обрезаны, строки, содержащие 4 , совпадения, содержат только 4.

Самый простой grep код, который будет работать:

 grep -xE '([^,]*,){10}[^,]*' 

Объяснение:

-x гарантирует, что шаблон должен соответствовать всей строке, а не только ее части. Это важно, поэтому вы не соответствуете строкам с более чем 10 запятыми.

-E означает «расширенное регулярное выражение», что приводит к уменьшению обратного слэша в вашем регулярном выражении.

Круглые скобки используются для группировки, а затем {10} означает, что в скобках в строке шаблона должно быть ровно десять совпадений.

[^,] является символьным классом – например, [cf] будет соответствовать любому одиночному символу, который является c , a, d , e или f , а [^AZ] будет соответствовать любому одиночному символу, который НЕ является заглавной буквой , Таким образом, [^,] соответствует любому одиночному символу, кроме запятой.

* После класса символа означает «ноль или более».

Таким образом, часть регулярного выражения ([^,]*,) означает «Любой символ, кроме запятой, любое количество раз (включая нулевые времена), за которым следует запятая», а {10} указывает на 10 из них. Затем [^,]* чтобы соответствовать остальным не запятым символам в конце строки.

Выбрасывание короткого python :

 #!/usr/bin/env python2 with open('file.csv') as f: print '\n'.join(line for line in f if line.count(',') == 10) 

Это будет читать каждую строку и проверять, соответствует ли число запятых в строке 10 line.count(',') == 10 , если это так, будет строка.

И вот путь Perl:

 perl -F, -ane 'print if $#F==10' 

Параметр -n заставляет perl читать свой файл ввода строки за строкой и выполнять скрипт, заданный -e в каждой строке. Параметр -a включает автоматическое разделение: каждая строка ввода будет разделена на значение, заданное параметром -F (здесь, запятая) и сохраняется как массив @F .

$#F (или, более общий $#array ), является самым высоким индексом массива @F . Поскольку массивы начинаются с 0 , строка с 11 полями будет иметь @F из 10 . Поэтому сценарий печатает строку, если она имеет ровно 11 полей.

Если поля могут содержать запятые или символы новой строки, ваш код должен понимать csv. Пример (с тремя столбцами):

 $ cat filter.csv a,b,c d,"e,f",g 1,2,3,4 one,two,"three ...continued" $ cat filter.csv | python3 -c 'import sys, csv > csv.writer(sys.stdout).writerows( > row for row in csv.reader(sys.stdin) if len(row) == 3) > ' a,b,c d,"e,f",g one,two,"three ...continued" 

Я полагаю, что большинство решений до сих пор отбрасывали вторую и четвертую строки.

  • Как объявить данные R CSV как числовые?
  • Как я могу преобразовать этот файл excel, чтобы он был не только одной строкой?
  • Сравните два файла с четырьмя столбцами
  • Поиск среднего значения, исключая первую строку
  • Экспорт данных netstat из терминала в файл csv
  • Реструктуризация CSV-файла
  • Как объединить все CSV S в один CSV в порядке
  • awk, когда оба разделителя и кавычки используются для поля
  • Как преобразовать мои текстовые файлы (каждый из которых содержит пару имени пользователя + пароль) в CSV, чтобы импортировать их в KeePass через bash (cygwin)
  • Удаление строк из шаблона в обратном порядке
  • Итерация через csv и печать определенных элементов
  • Как заставить excel интерпретировать китайские символы в CSV-файле
  • Interesting Posts

    xfreerdp продолжает отключать

    Как разбить несколько столбцов на два столбца на основе первого столбца

    Удалить параметры выключения / перезагрузки из окна выхода

    Как правильно скомпилировать gcc toolchain с помощью специального sysroot?

    Ограничить вывод из непрерывного процесса

    Получение отдельных байтов из двоичного файла в переменную с bash

    / usr / bin / время программы C с ввода-вывода не дает результатов

    AIX ftpd – как установить umask для данного пользователя?

    Добавьте одну строку ко всем найденным файлам

    Можно ли открыть терминал с указанными tty / pty

    Как добавить заголовок лицензии рекурсивно для всех файлов .h и .cpp в каталоге

    Почему Bash не принимает `&> & 3`, т.е. перенаправляет stdout и stderr в дескриптор файла 3?

    Bash – переименовать 'Image (x) .png' файлы

    Не удается создать клиентский сертификат после того, как я стал его собственным центром сертификации

    Проблема использования диска / Linux

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