Удаление строк не более или меньше полей 'N'?

Я работаю над mac с sed, perl, awk, bash ..

У меня есть текстовый файл большого размера (10 ГБ), который имеет 13 полей (столбцов) данных с разделителями TAB . К сожалению, некоторые из этих строк имеют посторонние TABs , поэтому я хочу удалить всю строку, где у нас есть дополнительные TABs , и, следовательно, неравные поля. (Я не возражаю, чтобы полностью отказаться от строк)

В настоящее время я записываю количество полей в другой файл.

 awk -F'\t' '{print NF}' infile > fieldCount head fieldCount 13 13 10 13 13 13 14 13 13 13 

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

  1. скорость полезна, поскольку я должен делать это по нескольким файлам
  2. делать это за один прогон было бы круто
  3. В настоящее время я переношу файл fieldCount в Python, пытаясь загружать строки за строкой.

РЕДАКТИРОВАТЬ:

vaild (13 столбцов)

 abcdefghijklm 

недействительный (14 столбцов)

 abcdefghijklmn 

У вас уже есть это:

  awk -F '\ t' 'NF == 13 {print}' infile > newfile 

И, если вы находитесь в одной из тех систем, где вы заряжаетесь нажатием клавиши (:)), вы можете сократить это до

  awk -F '\ t' 'NF == 13' infile > newfile 

Чтобы сделать несколько файлов за одну развертку и фактически изменить файлы (а не просто создавать новые файлы), scharf имя файла, который не используется (например, scharf ), и выполните цикл, например:

  для f в списке
 делать
     awk -F '\ t' 'NF == 13 {print}' "$ f"> scharf && mv -f - scharf "$ f"
 сделанный 

list может быть одним или несколькими именами файлов и / или шаблонами расширения имен подстановочных знаков; например,

  для f в blue.data green.data * .dat orange.data red.data /ultra/violet.dat 

Команда mv перезаписывает входной файл (например, blue.data ) временным файлом scharf (который имеет только строки из входного файла с 13 полями). (Убедитесь, что это то, что вы хотите сделать, и будьте осторожны. Чтобы быть в безопасности, сначала необходимо создать резервные копии своих данных.) -f указывает mv на перезапись входного файла, даже если он уже существует. -- защищает вас от странности, если у любого из ваших файлов есть имя, начинающееся с - .

Поскольку это большой файл, возможно, стоит использовать несколько более сложный инструмент для повышения производительности. Обычно специализированные инструменты быстрее, чем обычные инструменты. Например, решение одной и той же проблемы с cut имеет тенденцию быть быстрее, чем grep который имеет тенденцию быть быстрее, чем sed который имеет тенденцию быть быстрее, чем awk (обратная сторона заключается в том, что более поздние инструменты могут делать то, что раньше не может).

Вы хотите удалить строки с 13 символами табуляции или более, так что:

 LC_ALL=C grep -Ev '(␉.*){13}' 

или, может быть (я не ожидаю измеримой разницы в производительности)

 LC_ALL=C grep -Ev '(␉.*){12}␉' 

где – буквальный символ табуляции. Установка языкового стандарта на C не требуется, но ускоряет некоторые версии GNU grep по сравнению с многобайтовыми локалями.

С perl :

 perl -F'\t' -anle 'print if @F == 13' file 

для редактирования inplace, add -i :

 perl -i.bak -F'\t' -anle 'print if @F == 13' file