Вы никогда не сможете писать в файл, на который у вас нет прав на запись. Однако вы можете удалить этот файл, если у вас есть права на запись в каталог.
Уловка, которую использует 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
Утилита 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
— номер строки, которую мы пропускаем вперед, когда наш шаблон триггера совпадает.
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 -соответствие -шаблону для деталей и других связанных идиом.