Я, черт возьми, сделал это:
Добавьте пользователя (например, ник), который будет запускать sl, в файл sudoers
[nick@houston ~]$ sudo grep nick /etc/sudoers
nick ALL=(ALL) NOPASSWD: ALL
Откройте 2 сеанса шпатлевки, скажем, / dev / pts / 0
и ] / dev / pts / 1
Войдите в / dev / pts / 1
с любым пользователем
Войдите в / dev / pts / 0
с ником пользователя
и выполните следующую команду:
sl | sudo tee /dev/pts/1
awk '/This is a unique line/,/Common/{
H = H RS $0
if ( $0 ~ /Common/ ) {
g = H
sub("\n","",g)
sub("some","different",g)
sub("unique","changed",g)
$0 = g H
} else { next }
}1' inputfile
Вот код sed
(я показал в разделе ответов), переведенный на awk
.
Обратите внимание, что код, который у вас есть, берет на себя ответственность за включение/выключение флага переменной awk
для отслеживания строк. Но тогда как awk
уже делает для вас то же самое под капотом, когда вы используете его оператор range
,
Используйте ex
, указанный POSIX файловый редактор (и невизуальную форму vi
).
printf '%s\n' '/This is a unique line' '.,/Common/copy -' %p | ex file.txt
Это распечатывает измененное содержимое файла, но не сохраняет изменения.
Вот команда для сохранения изменений:
printf '%s\n' '/This is a unique line' '.,/Common/copy -' x | ex file.txt
В отличие от Awk и Sed, ex
не ограничивается только измененными строками по порядку. Скорее, он может работать со всем буфером, а не только вперед.
Первая команда /Это уникальная строка
— это просто команда движения. Он перемещает курсор на первую строку файла, содержащую Это уникальная строка
.
Следующая команда — это команда copy
. Он работает с диапазоном адресов от текущей строки (.
) до следующей строки оттуда, соответствующей Common
, и копирует их в строку, предшествующую текущей строке (-
).
Обновление: для модификации после копирования давайте сначала отметим строку, с которой мы начали. Первая копируемая строка будет отмечена буквой «b», а строка перед ней будет отмечена буквой «a». Затем скопированные строки будут помещены между 'a и 'b, и мы сможем использовать их в адресах для наших "замещающих" команд. Кстати, t
является синонимом copy
.
printf "/Here is a unique line
kb
-ka
.,/Common/t 'a
'a+,'b-s/unique/changed/g
'a+,'b-s/some/different/g
x
" | ex file.txt
sed -e '
/This is a unique line/,/Common/!b
H
/Common/!d
g
s/^\n//
h
s/unique/changed/
s/some/different/
G
' yourfile
H
BTW.