как я могу распечатать Энное и строку Mth выше или ниже согласующего отрезка длинной линии с grep?

sh (как в sh спецификация языка), не идет со строчным редактором. Терминальные драйверы имеют элементарный строчный редактор, которые позволяют, чтобы клавиша Backspace и несколько других ключей отредактировали вводимую строку, но обычно не клавиши со стрелками.

Можно вставить значение по умолчанию в терминальный входной буфер драйвера с помощью TIOCSTI ioctl как:

printf 'Please enter the value: '
value=the-default
perl -MPOSIX -e 'require "sys/ioctl.ph"; tcflush 0,2;
  ioctl(STDIN, &TIOCSTI, $_) or die "$!\n"
    for split "", join " ", @ARGV' "$value"
IFS= read -r value

На read, содержание $value (the-default) будет вставлен как будто введенный.

Теперь, если Вы хотите более усовершенствованный строчный редактор, любят обеспеченный libreadline где можно использовать клавиши со стрелками, можно использовать вещи как rlwrap (не стандартная команда, хотя):

value=the-default
value=$(rlwrap -S 'Please enter the value: ' -P "$value" -o cat)

rlwrap обычно используется для добавления a readline- как строчные редакторы к приложениям, которые не имеют того. Выше мы добавляем строчный редактор к cat, и использование его в одноразовом режиме (-o), так, чтобы cat возвраты после одной строки вводятся (хотя можно все еще ввести больше чем одну строку с Ctrl+V, Ctrl-J как в bash.

Если Вы готовы использовать нестандартные оболочки, zsh или bash имейте builtins для того использования их собственного строчного редактора.

В zsh:

value=the-default
vared -p 'Please enter the value: ' value

В bash:

value=the-default
IFS= read -re -i "$value" -p 'Please enter the value: ' value
2
10.06.2014, 10:54
5 ответов

Это сработало:

sed -n '/eth/{n;p;n;n;n;p;}' file
  • Поиск строки eth
  • n;: пропустить строку, p;: выведите строку
  • n;n;n;: пропустите 3 строки и выведите еще раз

Edit:

Это выведет строку выше, строку после и строку после 3 строк:

sed -n -e '/eth/{x;1!p;g;$!n;p;n;n;n;p;D;}' -e h file

И ваш второй вопрос: Я думаю, что вы не сможете набрать 20 раз команду n;...

...
2
27.01.2020, 22:00

Попробуйте эту awk-команду,

$ awk '$1~/^eth/ {getline; print; getline; getline; getline; print}' file
          inet addr:10.179.113.125  Bcast:10.179.113.127  Mask:255.255.255.248
          RX packets:1169385 errors:0 dropped:0 overruns:0 frame:0
          inet addr:10.254.4.1  Bcast:10.254.4.255  Mask:255.255.255.0
          RX packets:3806158038 errors:0 dropped:23193484 overruns:0 frame:0

Обновление:

$ awk '$1~/^eth/ {print previous; getline; print; getline; getline; getline; print}{previous=$0}' file
Mon Jun 9 00:11:47 CST 2014
           inet addr:10.179.113.125  Bcast:10.179.113.127  Mask:255.255.255.248
           RX packets:1169385 errors:0 dropped:0 overruns:0 frame:0
Tue Jun 10 05:11:47 CST 2014
           inet addr:10.254.4.1  Bcast:10.254.4.255  Mask:255.255.255.0
           RX packets:3806158038 errors:0 dropped:23193484 overruns:0 frame:0
1
27.01.2020, 22:00

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

0
27.01.2020, 22:00

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

perl -n00E '
    @eth_records= grep {/eth/} split/(?=>Mon|Tue|Wed|Thu|Fri|Sat|Sun)/;
    @lines_to_print = qw{1 3 6};
    map { $_-- } @lines_to_print;
    $sep = "-"x80;
    for(@eth_records){
        say $sep;
        say for (split/\n/)[ @lines_to_print ];
        say $sep
    }' your_file

Это разбивает файл на записи в строках, начинающихся с имени дня, и печатает 1-ю 3-ю и 6-ю строки всех записей, соответствующих /eth/

Обратите внимание, что он загрузит весь ваш файл в память, так что избегайте этого, если ваш файл большой.

1
27.01.2020, 22:00

Вот несколько предложений:

  • grep

     grep -P 'CST | inet | RX p' file
     

    Это напечатает все строки, содержащие CST или inet , за которыми следует пробел или RX pa . -P активирует Perl-совместимые регулярные выражения, что позволяет нам использовать | как логическое ИЛИ. Вы также можете добиться того же с помощью любого из

     grep -E 'CST | inet | RX p' file
     

    или

     grep 'CST \ | inet \ | RX p' файл
     
  • sed

     sed -n '/ CST \ | inet \ | RX p / p' файл
    sed -rn '/ CST | inet | RX p / p' файл
     

    Та же идея, что и выше, -n подавляет печать любых строк, а // p означает печать тех строк, которые соответствуют шаблону.

  • perl

    Вы можете использовать тот же подход в Perl:

      perl -ne 'print if / CST | inet | RX p /' file
     

    Или вы можете сделать что-то вроде

      perl -ne '$ k = 1 if / CST /;  напечатать, если $ k == 1 || $ k == 3 || $ k == 6;  $ k ++ 'файл
     

    Здесь переменная $ k устанавливается в 1, если строка соответствует CST , и увеличивается на единицу после чтения каждой строки. Строка затем печатается, если $ k имеет значение 1,3 или 6. Это более расширяемый подход.

    В качестве альтернативы, если вы знаете номера строк, которые хотите напечатать, было бы просто распечатать их напрямую ( $. - текущий номер строки):

     perl -ne 'print if $  . == 1 || $. == 3 || $. == 6 || $. == 11 || $. == 13 || $. == 16 'файл
     

    или, более идиоматично:

     perl -ne '@ d = (1,3,6,11,13,16);  напечатать, если файл $.~~@d '
     

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

     perl -e '@F = <>;  напечатать @F [0,2,5,10,12,15] 'файл
     
  • awk

    Вы можете использовать те же базовые подходы в awk , где NR - текущий номер строки:

     awk '/ CST | inet | RX p /'  файл
     

    или

     awk '{if (/ CST /) {k = 1} if (k == 1 || k == 3 || k == 6) {print} k ++;}' файл
     

    или

     awk 'NR == 1 || NR == 3 || NR == 6 || NR == 11 || NR == 13 || NR == 16' файл
     
0
27.01.2020, 22:00

Теги

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