Попробуйте sed:
sed 's/\(1 Q0\).*\/\(.*\)\.xml\( .*\)/\1 \2\3/' file
ИЛИ
sed 's/\(.*\)\/home.*\/\(.*\)\.xml\( .*\)/\1\2\3/' file
Вывод:
1 Q0 120411 1
1 Q0 105016 2
1 Q0 149972 3
1 Q0 110688 4
Может быть, вы можете «использовать grep для всех входных данных»? Используяnc
(netcat ), или через script
, или через другие подобные инструменты? Особенно, если ваш файл шаблонов имеет управляемый размер (, скажем, менее 1000 регулярных выражений ).
Первый пример:Вы можете egrep
некоторое потоковое соединение :(здесь показан пример с nc
, но могут применяться и другие)
prompt:/some/path $ nc somehost someport | egrep -f patternfile | gzip -c - > results.gz
# and while this is running, you can have a look at the growing results.gz:
prompt:/some/otherpath $ tail -f /some/path/results.gz | gzip -c - | less
(примечание :вы можете даже:touch /some/path/results.gz
перед запуском команды nc
и иметь tail -f
в этом (пустом )файле, чтобы ничего не пропустить. Так или иначе, в results.gz будет все, что вы хотели поймать)
второй пример:Вы даже можете egrep
в текущем сеансе оболочки (и показать другой способ отслеживания прогресса):
#in 1 terminal:
prompt:/home/userA $ script
Script command is started. The file is typescript.
prompt:/home/userA $
... doing here whatever you want (start IRC? etc)...
prompt:/home/userA $ ctrl-d # to end the current script session
Script command is complete. The file is typescript.
#and in another terminal, while you are "doing here whatever you want" :
prompt:/home/somewhere $ tail -f /home/userA/typescript | egrep -f patternfile | tee /some/place/to/store/results.gz
egrep
— это высокоэффективная версия grep
для большинства систем. (см. интересную информацию о:https://swtch.com/~rsc/regexp/regexp1.html)
I can't use grep on all of the input since it's a stream. I can accumulate a chunk of stream and use grep on it...
Вы в курсе, что трубопроводы блокируются? Если вы передаете что-то в grep, а все входные данные недоступны, grep будет ждать, пока они не будут доступны, а затем продолжит работу, как если бы входные данные были там все время.
$ ( echo a1; echo b1; sleep 5; echo a2 ) | grep 'a.'
a1
a2
РЕДАКТИРОВАТЬ :Как работают конвейеры, например, с cmd1 | cmd2
, обе программы запускаются одновременно, например, с. 65 536 -байт «буфера фрагментов» между ними. Когда cmd2
пытается прочитать, а этот буфер пуст, он будет ждать, пока фрагмент станет доступным. Когда cmd1
пытается записать и этот буфер заполнен, он будет ждать, пока cmd2
не прочитает его.
Из того, что я могу прочитать, нет необходимости разбивать входные данные на куски и передавать их в grep отдельно. Это уже сделано автоматически.
EDIT2:grep
также должен печатать результаты, как только находит их в потоке. Нет необходимости, чтобы поток заканчивался, прежде чем вы сможете получить свои результаты.