Что можно использовать для удаления текущей и следующих 20 строк для каждого совпадения в файле?

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

Уловка, которую использует VIM, заключается в удалении файла и записи нового.

Можно показать, что этот метод использует VIM без чтения исходного кода, проверив номер инода до и после:

$ touch foo
$ chmod u-w foo
$ ls -li foo
60818465 -r--r----- 1 philip philip 0 Feb 25 10:24 foo
$ vi foo
$ # edit the file and save with :w!
$ ls -li foo
60818467 -r--r----- 1 philip philip 8 Feb 25 10:25 foo

Обратите внимание, что номер инода изменился, показывая, что новый файл НЕ является тем же файлом, что и тот, который вы редактировали.


К вашему сведению, моя текущая конфигурация очень короткая:

runtime! debian.vim
if has("syntax")
  syntax on
endif
set tabstop=4
set autoindent

Установлены пакеты Debian:

vim                               2:8.1.0875-1
vim-common                        2:8.1.0875-1
vim-runtime                       2:8.1.0875-1
vim-tiny                          2:8.1.0875-1

-1
30.09.2021, 23:12
2 ответа

Утилита grepбыла бы практически бесполезна в этой ситуации, так как нет способа исключить строки на основе совпадения с какой-либо предыдущей строкой. (своего рода отрицание смысла опции -A, доступной в некоторых реализацииgrep).

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

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

sed '/^"my-thread-[[:digit:]]\{1,\}".*waiting on conditon/ { N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;d; }' file

Мы могли бы применить аналогичный подход с awk.

awk '/^"my-thread-[[:digit:]]+".*waiting on conditon/ { for (i=0; i<20; ++i) getline; next }; 1' file

Или, поскольку awkзнает, на какой строке он находится, мы можем пропустить 20 строк вперед.

awk 'FNR < skip_to { next } /^"my-thread-[[:digit:]]+".*waiting on conditon/ { skip_to = FNR+21; next }; 1' file

В приведенном выше коде FNR— это специальная переменная, содержащая номер строки в текущем файле, а skip_to— номер строки, которую мы пропускаем вперед, когда наш шаблон триггера совпадает.

0
01.10.2021, 06:25
awk '/my-thread-.*waiting on condition/{c=21} !(c&&c--)' file

напр.:

$ seq 20 | awk '/3/{c=6} !(c&&c--)'
1
2
9
10
11
12
19
20

$ seq 20 | awk '/3/{c=11} !(c&&c--)'
1
2

См. печать -с -sed -или -awk -a -строка -после -a -соответствие -шаблону для деталей и других связанных идиом.

0
01.10.2021, 12:47

Теги

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