Удалите строку, содержащую определенную строку и следующую строку

Вы имеете HashKnownHosts набор к"yes"в Вашем ssh_config файл, таким образом, имена хостов не доступны в простом тексте.

Если Вы знаете имя хоста, Вы ищете заранее, можно искать его с:

    ssh-keygen -H -F hostname

Вот соответствующий раздел от ssh-keygen(1) страница справочника:

 -F hostname
         Search for the specified hostname in a known_hosts file, listing
         any occurrences found.  This option is useful to find hashed host
         names or addresses and may also be used in conjunction with the
         -H option to print found keys in a hashed format.

72
15.12.2015, 03:25
5 ответов

Если у Вас есть GNU sed (таким образом, не встроил Linux или Cygwin):

sed '/bar/,+1 d'

Если Вы имеете bar на двух последовательных строках это удалит вторую строку, не анализируя его. Например, если у Вас есть файл с 3 строками bar/bar/foo, foo строка останется.

77
27.01.2020, 19:31
  • 1
    +1 для длины :) В моем конкретном примере я не имею последовательными bars, таким образом, этого супер легко помнить. –  jakub.g 20.11.2012, 11:30
  • 2
    sed '/bar/d' если Вы просто хотите "Удалить строку, содержащую определенную строку" а не следующее. –  AJP 02.04.2017, 12:55
  • 3
    Если я хочу удалить все строки после математики затем? –  Pandya 07.02.2018, 11:24
  • 4
    @Pandya, Это отличается. Можно использовать, например. sed '/math/q' –  Gilles 'SO- stop being evil' 07.02.2018, 14:44

Если bar может произойти на последовательных строках, Вы могли сделать:

awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile

который может быть адаптирован для удаления больше чем 2 строк путем изменения 2 выше с количеством строк для удаления включая соответствующую.

В противном случае в этом легко выполняют sed с @MichaelRollins' решением или:

sed '/bar/,/^/d' < infile > outfile
17
27.01.2020, 19:31
  • 1
    Другой плюс в решении AWK - то, что я могу заменить /bar/ с /bar|baz|whatever/. В sed тот синтаксис, кажется, не работает. –  jakub.g 21.11.2012, 11:58

Я не бегло говорю на sed, но легко сделать так в awk:

awk '/bar/{getline;next} 1' foo.txt 

awk чтения сценария: для строки, содержащей панель, получите следующую строку (getline), затем пропустите всю последующую обработку (затем). 1 шаблон в конце печатает остающиеся строки.

Обновление

Как указано в комментарии, вышеупомянутое решение не работало с последовательным bar. Вот пересмотренное решение, которое принимает его во внимание:

awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt 

Мы теперь продолжаем читать для пропуска всех/bar/строк.

12
27.01.2020, 19:31
  • 1
    Копировать grep -A 100%, также необходимо обработать любое количество последовательных bar строки правильно (путем удаления целого блока и 1 строки после). –  jw013 19.11.2012, 19:07

Вы захотите использовать сценарии sed возможностей выполнить это.

$ sed -e '/bar/ { 
 $!N
 d
 }' sample1.txt

Демонстрационные данные:

$ cat sample1.txt 
foo
bar
biz
baz
buz

Команда "N" добавляет следующую строку входа в пространство шаблона. Это объединилось со строкой от соответствия шаблона (/, панель/) будут строки, которые Вы хотите удалить. Можно затем обычно удалять с командой "d".

7
27.01.2020, 19:31
  • 1
    Как я ввожу новую строку в консоли? Или это только для сценария? –  jakub.g 20.11.2012, 11:35
  • 2
    @jakub.g: с GNU sed: sed -e '/bar/{N;d}' sample1.txt –  Cyrus 27.07.2014, 20:51

Если какая-либо строка, следующая сразу за совпадением, должна быть удалена, тогда ваша программа sed должна будет учитывать последовательные совпадения. Другими словами, если вы удалите строку, следующую за совпадением, которое также совпадает, то, вероятно, вам также следует удалить строку, следующую за ним.

Реализовано достаточно просто - но надо немного оглянуться.

printf %s\\n     0 match 2 match match \
                 5 6 match match match \
                 10 11 12 match 14 15  |
sed -ne'x;/match/!{g;//!p;}'

0
6
11
12
15

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

Итак, sed проверяет предыдущую строку на соответствие match , и если это ! не найдено, выполняются два выражения в { функции } . sed будет g et пространство удержания, перезаписав пространство шаблона - что означает, что текущая строка тогда находится как в пространстве удержания, так и в пространстве шаблона - а затем будет // проверьте его на соответствие его последнему скомпилированному регулярному выражению - match - и если оно не соответствует , это p ритированный.

Это означает, что строка печатается только в том случае, если она не соответствует и непосредственно предыдущая строка не соответствует . Он также исключает любые ненужные перестановки для последовательностей совпадений es.

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

printf %s\\n    1 2 3 4 match  \
                match match 8  \
                9 10 11 12 13  \
                14 match match \
                17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep

... замените 5 на количество строк (включая совпадающую строку) , которую вы хотите удалить ...


1
2
3
4
12
13
14
21
2
27.01.2020, 19:31

Теги

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