Как распечатать каждый n-й матч, используя awk - PullRequest
0 голосов
/ 07 марта 2011

Я пытаюсь разбить большой XML-файл на несколько файлов меньшего размера. Я нашел решение разделить каждый узел на отдельный файл:

awk '/<mono/{close("row"count".xml");count++}count{f="row"count".xml";print $0 > f}' file.xml 

Приведенный выше код соответствует каждому «моно» узлу и выводит его в строку имен файлов {rownumber} .xml. Как я могу напечатать каждые 20 совпадений в файл?

Ответы [ 2 ]

1 голос
/ 07 марта 2011

Я бы сказал, сохраняйте переменную count, и вам просто нужно изменить способ создания вашего имени файла: f="row" int(count/20) ".xml"

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

awk '
  /<mono/ {close f; count++; f = "row" int(count/20) ".xml"} 
  count {print >> f}
' file.xml
1 голос
/ 07 марта 2011

Поддерживать два счета - текущий и повторный счет. Выполняйте текущее действие (печатайте метку) только тогда, когда счетчик повторений по модулю 20 имеет соответствующее значение (0 и 1 в показанном коде):

awk '/<mono/ { if (repeat++ % 20 == 0) { close("row"count".xml"); count++ } }
     count && repeat % 20 == 1 { f = "row"count".xml"; print $0 > f}' file.xml

Условие '== 1' во втором условии немного неопрятно; вероятно, есть лучший способ справиться с этой логикой.

Обратите внимание, что ваш код обнаруживает '<monotonous>' как моно тоже.


Группировка записей 1-20 в файле1, 21-40 в файле2 и т. Д. *

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

awk '/<mono/ {   if (recno > 1 && recno % 20 == 0) { close(file); count++;}
                 if (recno % 20 == 0) { file = "row" count ".xml" }
                 print $0 > file
                 recno++
             }' file.xml

Первый файл будет row.xml. Последующие файлы row1.xml и т. Д.

Я проверил это на файле вроде этого:

<mono> <tonous val=001/> </mono>
ignore
<mono> <tonous val=002/> </mono>
<mono> <tonous val=003/> </mono>
<mono> <tonous val=004/> </mono>
<mono> <tonous val=005/> </mono>
ignore
<mono> <tonous val=006/> </mono>
<mono> <tonous val=007/> </mono>
<mono> <tonous val=008/> </mono>
<mono> <tonous val=009/> </mono>
ignore
<mono> <tonous val=010/> </mono>
<mono> <tonous val=011/> </mono>
<mono> <tonous val=012/> </mono>
<mono> <tonous val=013/> </mono>
<mono> <tonous val=014/> </mono>
ignore
<mono> <tonous val=015/> </mono>
<mono> <tonous val=016/> </mono>
<mono> <tonous val=017/> </mono>
<mono> <tonous val=018/> </mono>
<mono> <tonous val=019/> </mono>
ignore
<mono> <tonous val=020/> </mono>
<mono> <tonous val=021/> </mono>
<mono> <tonous val=022/> </mono>
<mono> <tonous val=023/> </mono>
ignore
<mono> <tonous val=024/> </mono>
...

Содержит 100 <mono> строк и разбрызгивание ignore строк (некоторые повторяются). Он производил файлы row.xml, row1.xml, ... row4.xml с 20 строками в каждом. Это было проверено на MacOS X 10.6.6 со стандартом (BSD) awk.

...