Удалять заголовки и содержимое из плоского файла, если они находятся ниже определенного количества строк

У меня плоский файл, содержащий около 10 миллионов строк:

query ID1 content1 content2 query ID2 content3 content4 ... content21 query ID3 content22 content23 ... content81 

Любой блок в файле менее 10 строк должен быть удален. Например, первый блок содержит 4 строки (запрос к контенту2), и он должен быть удален. Этот шаг необходимо выполнить, прежде чем разбивать блоки на отдельные файлы. Любое предложение?

2 Solutions collect form web for “Удалять заголовки и содержимое из плоского файла, если они находятся ниже определенного количества строк”

Может быть сделано с awk:

 awk ' # define a long block BEGIN{ long = 10; } # output long block when new block is found ($1 == "query" && n >= long){ print s; } # new block ($1 == "query"){ s = ""; n = 0; } # all lines { s = (s != "") ? s "\n" $0 : $0; n++; } # output the long block if it is the last one in the file END{ if (n >= long){ print s; } } ' input.file > output.file 
 sed -e:q -e'$!N;s/\n/&/9;tS' -e'$!bq' -e:S \ -e's|^query.*\n\(query\)|\1|;tq' -e'/\n/{P;D;}' 

Это будет поддерживать все 10 строк текущего входного файла в буфере sed . Для каждой регулярной входной линии sed будет P rint первой из своих буферных линий, а затем D elete it. В верхней части цикла N ext sed будет пополнять свой буфер с помощью строки ввода N ext.

Если в любом query.*\nquery точки query.*\nquery совпадает с его 10- query.*\nquery окном, sed удалит все, кроме совпадения с завершающим query . И в начале следующего цикла sed соберет вход, пока он не пополнит все десять строк своего буфера сдвижного окна, прежде чем пытаться снова протестировать входной сигнал.

Вот простая демонстрация:

 for i in 3 6 9 12 15 18 do printf "%s %s %s %s%0${i}s" query ID1 content1 content2 done| tr \ \\n| nl -ba -w1 | sed -e:q -e'$!N;s/\n/&/9;tS' -e'$!bq' -e:S \ -e's|^[0-9]*.query.*\n\([0-9]*.query\)|\1|;tq' \ -e'/\n/{P;D;}' 

Я слегка изменил регулярное выражение, чтобы разместить nl для вывода:

 16 query 17 ID1 18 content1 19 content2 20 21 22 23 24 25 26 27 28 query 29 ID1 30 content1 31 content2 32 33 34 35 36 37 38 39 40 41 42 43 query 44 ID1 45 content1 46 content2 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 query 62 ID1 63 content1 64 content2 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 

sed отсекает все последовательности, которые полностью соответствуют его входному окну. Он не пропустит ни одного, и ему не нужно буферизировать больше, чем десять строк за раз. Если мы добавим l ook в скрипт sed мы увидим, как выглядит его буфер:

 for i in 3 6 9 12 15 18 do printf "%s %s %s %s%0${i}s" query ID1 content1 content2 done| tr \ \\n| nl -ba -w1 | sed -ne:q -e'$!N;l;s/\n/&/9;tS' -e'$!bq' -e:S \ -e's|^[0-9]*.query.*\n\([0-9]*.query\)|\1|;tq' \ -e'/\n/{P;D;}' 

 1\tquery\n2\tID1$ 1\tquery\n2\tID1\n3\tcontent1$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery\n8\tID\ 1$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery\n8\tID\ 1\n9\tcontent1$ 1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery\n8\tID\ 1\n9\tcontent1\n10\tcontent2$ 7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t$ 7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t$ 7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t$ 7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t\n14\t$ 7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t\n14\t\n\ 15\t$ 7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t\n14\t\n\ 15\t\n16\tquery$ 16\tquery\n17\tID1$ 16\tquery\n17\tID1\n18\tcontent1$ 16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2$ 16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t$ 16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t$ 16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t\n22\t$ 16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t\n22\t\n23\ \t$ 16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t\n22\t\n23\ \t\n24\t$ 
  • Я бы хотел использовать одну из трех команд sed (диапазоны чисел)
  • Обратный grepping
  • Как я могу «объединить» шаблоны в одной строке?
  • Используйте sed, чтобы заменить часть строки переменной
  • Когда использовать grep, less, awk, sed
  • заменяя точку символом с помощью sed или perl
  • Создание файла из другого файла на основе числового значения в каждой строке
  • sed regexp HEX char
  • Как манипулировать CSV-файлом с помощью sed или awk?
  • Как разместить данные, ограниченные скобками, в одной строке?
  • sed string с плохими символами
  • Как сокращать / путь / в / файл в / p / t / файл
  • Interesting Posts

    Есть ли способ найти все ресурсы X, которые использует приложение?

    502 Ошибка прокси – запрос PUT для сервера MDM OSX через apache ProxyPass на ubuntu 14

    Содержимое файла удалено

    udev для устройства USB и игнорирование других

    Как предоставить разрешения другому пользователю после регистрации в качестве пользователя root в Linux?

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

    Простой скрипт Bash; Только работает?

    Можно ли настроить auth.log о том, какой ключ был использован?

    Установите ffmpeg на Netgear NAS, выполнив произвольное сжатие Debian

    Bash автоматически перезагружает (впрыскивает) обновления в исполняемый скрипт при его сохранении: Почему? Любое практическое применение?

    Как создать простой .txt (текстовый) файл с помощью терминала?

    Как автоматически запустить мой bash_profile?

    Все ли дистрибутивы Linux и настольные среды должны быть открытыми?

    отключить ведение журнала Xserver

    Настроить ошибку «Компилятор C не может создавать исполняемые файлы»

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