Печать NTH Range с SED

Посмотрите на autossh. В нем есть поддержка переподключения потерянных туннелей. Я оставлю ссылку. В статье предлагается поместить его в /etc/rc.local, что я и сделал в Debian.

http://linuxaria.com/howto/permanent-ssh-tunnels-with-autossh

2
05.08.2018, 14:03
3 ответа

Легче сделать с awk, предполагая, что блоки, определенные [и ], сами по себе не содержат [или ]внутри блока

$ awk -v b=2 '/\[/{c++} c==b; /]/ && c==b{exit}' ip.txt
[
eighth 
]
  • -v b=2переменная, указывающая, какой блок требуется
  • /\[/{c++}увеличить счетчик, если линия соответствует начальному условию
  • c==b;распечатать входную запись, если счетчик равен требуемому блоку
  • /]/ && c==b{exit}выход при совпадении конечного условия

другой способ написать это:

awk -v b=2 '/\[/{c++} c==b{print $0; if(/]/) exit}' ip.txt
1
27.01.2020, 22:09
$ sed -n '/^\[/h; /^\[/,/^\]/H; ${x;s/^\[\n//;p;}' file
[
eighth
]

Аннотированный sedскрипт (предполагает-n):

/^\[/h;         # replace hold space with this line
/^\[/,/^\]/H;   # append these lines to hold space with embedded newlines
${              # at last line of input
    x;          # swap in the hold space
    s/^\[\n//;  # delete the first "[" and the newline following it
    p;          # print
}

То есть всякий раз, когда мы находим строку, начинающуюся с [, очищаем пространство хранения, копируя туда строку. Затем продолжайте добавлять строки в пространство хранения, пока не найдем соответствующую строку, начинающуюся с ].

В конце у нас будет пробел с одним [лишним, поэтому удалите это (и встроенный символ новой строки после него )перед печатью данных.

1
27.01.2020, 22:09

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

sed -ne '                    ;# "-n" suppresses autoprint of pattern space
    /^\[/!d                  ;# skip lines that donot begin a fresh block
    :a;$!N;/\n]/!ba          ;# keep appending lines to pattern space until end of block
    G                        ;# append our makeshift counter (hold space) to pattern spc
    s/\n\{2\}$//p            ;# only when counter had 2 chars in it, we print block
    /\n$/!q                  ;# target block, 2nd block has been printed so quit 
    x;s/$/\n/;x              ;# target block not reached, so increment
' input.file

с Perl, мы можем использовать оператор ...в тандеме с логическим значением $k == 2, указывающим, что мы достигли предполагаемого целевого блока и должны его распечатать.

perl -lne 'print if /^\[/ && ++$k == 2... /^]/' input.file    
0
27.01.2020, 22:09

Теги

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