Возможно, есть инструменты, чтобы сделать это быстрее, но вы могли бы потреблять первый файл в цикле и проверять как
while read -r pat; do
if grep -q "$pat" fileB; then
printf '%s has a match' "$pat"
fi
done < fileA
grep
определен для сопоставления, сохранения или отбрасывания строк, поэтому он должен прочитать всю строку перед выполнением сопоставления; это не может выполнить то, что вы хотите.
Сначала вам нужно проверить, выполняет ли команда
это эхо-вывод входных символов один за другим в конвейер. Стандартные программы C (а иногда и другие программы, использующие C stdio) по умолчанию используют строчную буферизацию, когда stdout является «интерактивным устройством», как определено реализацией, но в противном случае полная буферизация, а pipe обычно не определяется как интерактивный. Ваша команда
уже ведет себя необычно на tty, но проверьте, что она по-прежнему ведет себя так на конвейере с помощью команды command | dd bs = 1
.
Если это не сработает, вам понадобится программа, которая устанавливает псевдо-tty (pty) для команды
, например урезанный сценарий
, предложенный Марк Плотник.
Если эхо в канал работает на стороне команды
, все, что вам нужно, это что-то с правой стороны канала, которое не дожидается полной строки. Это может сделать простая программа на C, например:
#include <stdio.h>
int main (void) {
setvbuf (stdout, NULL, _IONBF, 0);
int c;
while( (c = getchar()) != EOF ){
int sel = c != '%';
for( ; c != '\n' && c != EOF; c = getchar() )
if( sel ) putchar (c);
if( sel ) putchar ('\n');
}
}
Или, если у вас есть bash
- а встроенные устройства IMLE, как правило, НЕ используют - попробуйте сценарий, содержащий
IFS=$'\n'
while read -rn1 c; do y=true; [[ "$c" == "%" ]] && y=false;
while ! [[ "$c" == "" ]]; do $y && printf "%c" "$c"; read -rn1 c || exit; done
$y && printf "\n"; done
sed
имеет небуферизованный режим, поэтому следующее должно работать также:
... | sed -u -r '/%[^\n]*\n/d'
В начале строки используется ^
, а в конце строки - $
. Символы \ n
не распознаются. И конец строки никогда не сопоставляется (по умолчанию).
Поэтому вам следует использовать что-то вроде
grep -v "^%. * $"
.