Найдите все происшествия в файле с sed

Большинство сенсорных экранов будет работать с Linux; пока аппаратные средства не имеют некоторого поставщика определенным коннектором (большая часть fondleslabs, я видел, USB), затем, можно, вероятно, добраться, это, чтобы продолжить работать *отклоняет, хотя как с большинством вещей, может быть некоторая требуемая конфигурация.

Если поставщик говорит 'совместимый с *, отклоняют', на поле затем это - больше garuantee, что это будет работать - но если они не делают, более вероятно, что они не протестировали или не потрудились помещать его на поле, а не устройство, являющееся по сути несовместимым с *, отклоняют систему.

Вы могли всегда спрашивать ритейлера в любом случае, и лично я буду видеть, мог ли я испытать его сначала, потому что Вы действительно получаете некоторые очень дешевые, но также и очень очень плохие.

P.S. умный с полуслова понимает: обычно, вопросы о совете покупок находятся вне темы на сайтах обмена стека, лучший способ попросить, чтобы это должно было бы сказать, 'Как может я говорить, работал ли монитор с сенсорным экраном с Linux' или, 'Что искать в сенсорном экране для Linux'.

15
24.07.2014, 20:27
9 ответов

Вот попытка эмулировать grep -B3 с помощью сдвигающегося окна sed, основанная на этом GNU sed примере (но, надеюсь, POSIX-совместимом - с подтверждением @StéphaneChazelas):

sed -e '1h;2,4{;H;g;}' -e '1,3d' -e '/141\.299\.99\.1/P' -e '$!N;D' file

Первые два выражения формируют многострочный буфер шаблона и позволяют ему обрабатывать крайний случай, когда перед первым совпадением имеется менее 3 строк предыдущего контекста. Среднее выражение (regex match) распечатывает строку с верхней части окна до тех пор, пока нужный текст совпадений не пройдет через буфер шаблона. Окончательное $!N;D прокручивает окно на одну строку, за исключением тех случаев, когда оно достигает конца ввода.

4
27.01.2020, 19:49

В большинстве из них /141.299.99.1/ также будет соответствовать (например) 141a299q99+1 или 141029969951, потому что . в регулярном выражении может представлять любой символ.

Использование /141[...]299[...]99[...]1/ более безопасно, и вы можете добавить дополнительный контекст в начало и конец всего регенерата, чтобы он не совпадал с 3141., .12, .104, и т.д.

.
1
27.01.2020, 19:49

grep сделает лучше:

grep -B 3 141.299.99.1 TESTFILE

The -B 3 означает вывести три строки перед каждым совпадением. Это позволит вывести -- между каждой группой строк. Чтобы отключить эту функцию, используйте также -no-group-separator.

Опция -B поддерживается GNU grep , а также большинством версий BSD (OSX, FreeBSD, OpenBSD, NetBSD), но технически это не является стандартной опцией.

10
27.01.2020, 19:49

Когда это возможно, можно использовать pcregrep:

pcregrep -M '.*\n.*\n.*\n141.299.99.1' file
4
27.01.2020, 19:49

Если ваша система не поддерживает контекст grep , вы можете вместо этого попробовать ack-grep :

ack -B 3 141.299.99.1 file

ack - это инструмент как и grep, оптимизированный для программистов.

4
27.01.2020, 19:49
awk '/141.299.99.1/{for(i=1;i<=x;)print a[i++];print} {for(i=1;i<x;i++)
     a[i]=a[i+1];a[x]=$0;}'  x=3 filename

В данном решении awk используется массив, который всегда будет содержать 3 строки перед текущим образцом. Таким образом, при совпадении шаблона, содержимое массива вместе с текущим шаблоном распечатывается.

Тестирование

-bash-3.2$ cat filename
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
141.299.99.1
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
10.0.0.10
141.299.99.1
10.0.0.11
10.0.0.12
10.0.0.13
10.0.0.14
10.0.0.15
10.0.0.16
141.299.99.1
10.0.0.17
10.0.0.18
10.0.0.19

После выполнения команды выводится,

10.0.0.2
10.0.0.3
10.0.0.4
141.299.99.1
10.0.0.8
10.0.0.9
10.0.0.10
141.299.99.1
10.0.0.14
10.0.0.15
10.0.0.16
141.299.99.1
2
27.01.2020, 19:49

С помощью sed вы можете создать скользящее окно.

sed '1N;$!N;/141.299.99.1/P;D'

Вот и все. Но будьте осторожны - безумное поведение bash при расширении ! даже при цитировании !!! в командную строку из вашей истории команд может немного свести с ума. Приставьте к команде префикс set + H; , если вы обнаружите, что это так. Чтобы затем снова включить его (но почему ???) , после установите -H .

Это, конечно, применимо только в том случае, если вы использовали bash - хотя я так не думаю. Я вполне уверен , что вы работаете с csh - (это оболочка, чье безумное поведение bash имитирует расширение истории, но, может быть, и не до крайностей, оболочка c выдержала это) . Так что вероятно a \! должен работать. Я надеюсь.

Это весь переносимый код: POSIX описывает три своих оператора следующим образом: (хотя стоит отметить, что я только подтвердил, что это описание существовало еще в 2001 году)

[2addr] N Добавьте следующую строку ввода, за вычетом ее завершающей \ n ewline, в пространство шаблонов, используя встроенную \ n ewline, чтобы отделить добавленный материал от исходного материала. Обратите внимание, что текущий номер строки изменится.

[2addr] P Запишите пространство шаблонов до первой \ n ewline в стандартный вывод.

[2addr] D Удалите начальный сегмент пространства шаблонов через первую \ n строку и начните следующий цикл.

Итак, в первой строке вы добавляете дополнительную строку в пространство шаблона, так что это выглядит так:

^line 1s contents\nline 2s contents$

Затем в первую строку и каждую последующую строку - за исключением самой последней - вы добавляете еще одну линия к пространству образца. Это выглядит так:

^line 1\nline 2\nline 3$

Если ваш IP-адрес находится внутри вас, P ринт до первой новой строки, поэтому здесь просто строка 1. В конце каждого цикла вы D выбираете то же самое и начинаете с того, что осталось. Итак, следующий цикл выглядит так:

^line 2\nline 3\nline 4$

... и так далее. Если ваш ip должен быть найден на любом из этих трех, самый старый будет распечатываться - каждый раз. Так что вы всегда только на три строчки впереди.

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

seq 10 52 | sed '1N;$!N;/0\(\n\|$\)/P;D'

10
18
19
20
28
29
30
38
39
40
48
49
50

Это немного сложнее, чем в вашем случае, потому что мне пришлось чередовать либо 0 \ n новой строки, либо 0 $ конец пространства шаблонов, чтобы больше походить на вашу проблему - но они немного отличаются тем, что для этого требуется привязка - что может быть немного сложно сделать, поскольку пространство шаблонов постоянно смещается.

Я использовал нечетные случаи 10 и 52, чтобы показать, что до тех пор, пока якорь является гибким, результат остается неизменным. Полностью переносимый, я могу достичь тех же результатов, вместо этого полагаясь на алгоритм и выполняя:

seq 10 52 | sed '1N;$!N;/[90]\n/P;D'

И расширять поиск, ограничивая мое окно - с 0 до 9 и 0 и с 3 строк до двух.

Как бы то ни было, идею вы поняли.

9
27.01.2020, 19:49

Начиная с вы упоминаете , что у вас нет -B параметр grep , вы можете использовать Perl (например), чтобы сделать скользящее окно из 4 строк:

perl -ne '
    push @window,$_;
    shift @window if @window > 4;
    print @window if /141\.299\.99\.1/
' your_file

Ответ Рамеша делает то же самое с awk .

4
27.01.2020, 19:49

Вы можете реализовать тот же базовый подход, что и другие ответы, отличные от grep, в самой оболочке (это предполагает относительно недавнюю оболочку, которая поддерживает = ~ ):

while IFS= read -r line; do 
    [[ $line =~ 141.299.99.1 ]] && printf "%s\n%s\n%s\n%s\n" $a $b $c $line;
    a=$b; b=$c; c=$line; 
done < file 

В качестве альтернативы вы можете поместить весь файл в массив:

perl -e '@F=<>; 
        for($i=0;$i<=$#F;$i++){
          print $F[$i-3],$F[$i-2],$F[$i-1],$F[$i] if $F[$i]=~/141.299.99.1/
        }' file 
4
27.01.2020, 19:49

Теги

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