Метод программных инструментов, более эффективный для больших файлов, поскольку он считывает только конец файла, а затем останавливается, когда находит последнее совпадение:
tac sample.txt | grep -F -m1 -B 999999 '====' | head -n -1 | tac
Примечание. :увеличьте или уменьшите 999999
по мере необходимости, чтобы оно было длиннее любого возможного совпадения. Этот код будет работать лучше всего, если заранее известно, что последнее совпадение находится ближе к концу большого файла. См. также ответGlenn Jackman с вариантами awk
и sed
, которые позволяют избежать необходимости 999999
. Для систем с очень низкими ресурсами grep
более эффективен, чем awk
или sed
.
Чтобы избежать угадывания, некоторые дополнительные stat
уродства сработали бы:
f=sample.txt; tac "$f" | grep -F -m1 -B $(stat -c '%s' "$f") '====' |
head -n -1 | tac
Использование gnu sed с heredoc, содержащим строки, которые нужно добавить в файл конфигурации.
add=$(sed -e 's:^:\t:;s:\\:&&:g;$!s:$:\\:' <<!
---> Hello, world! <---
---> ok tata by by <---
!
)
sed -e '
/^\[Public]/,/^$/!b
/./{
$a\
'"$add"'
}
//!i\
'"$add"'
' /etc/samba/smb.conf
Я бы использовал awk
для этого
awk '/^\[Public\]/ {toggle=1} toggle && $0=="" {toggle=0; printf "\t%s\n", "hello world <--"} 1' /tmp/sed
При совпадении [Public]
устанавливается переключатель, а затем на первой строке нулевой -длины переключатель сбрасывается и вставляется требуемый текст.
awk '
/^\[Public\]/ {toggle=1} # or: $0=="[Public]"
toggle && $0=="" {toggle=0; printf "\t%s\n", "hello world <--"}
1
' /tmp/sed
Небольшой трюк с использованием awk
предполагает, что следующий блок начинается после этого и, таким образом, использует \n[
в качестве разделителя записей. Удалить последние строки с head
из-за последнего разделителя записей.
awk 'BEGIN {RS="\n\\[";ORS="\n["}
/Block 1/ {$0 = $0"\toption3 = value3\n"} {print}' 1 |
head -n-2
профиль
other config
#and a comment
[Block 1]
option1 = value1
option2 = value2
[Block 2]
option1 = value1
option2 = value2
выход
other config
#and a comment
[Block 1]
option1 = value1
option2 = value2
option3 = value3
[Block 2]
option1 = value1
option2 = value2