grep в интерактивной программе

Возможно, есть инструменты, чтобы сделать это быстрее, но вы могли бы потреблять первый файл в цикле и проверять как

while read -r pat; do
    if grep -q "$pat" fileB; then
        printf '%s has a match' "$pat"
    fi
done < fileA
1
15.06.2016, 18:25
3 ответа

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
3
27.01.2020, 23:25

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

... | sed -u -r '/%[^\n]*\n/d'

0
27.01.2020, 23:25

В начале строки используется ^ , а в конце строки - $ . Символы \ n не распознаются. И конец строки никогда не сопоставляется (по умолчанию).

Поэтому вам следует использовать что-то вроде grep -v "^%. * $" .

0
27.01.2020, 23:25

Теги

Похожие вопросы