使用 sed 或 awk 进行多行字符串模式匹配、插入和删除

使用 sed 或 awk 进行多行字符串模式匹配、插入和删除

我正在尝试编写一个脚本来自动更新我的.ssh/config.基本上它是一个 ssh 管理工具,将为.ssh/config输入计算机、用户等添加条目。

问题:

是否有任何工具(如sed、 或awk)可用于自动插入或删除 的所有实例多线字符串?

例如使用sed命令:

# inserts "stuff" in the line above "single-line-pattern" in file
sed -i.bkp "/single-line-pattern/i stuff" file

# inserts "stuff" in the line below "single-line-pattern" in file
sed -i.bkp "/single-line-pattern/a stuff" file

# removes all instances of "single-line-pattern" from file
sed -i.bkp "/single-line-pattern/d" file

可能的解决方法

删除所有模式实例的一个巧妙的解决方法是反转问题并找到所有非实例,将它们打印到新文件,然后删除旧文件。忽略在条目上方附加(因为我将它们全部删除),我只是以固定顺序附加到文件末尾。

话虽如此,这并没有回答上述问题,也没有给出此类工具或sed/awk功能的示例多线字符串。

我的解决方案

下面给出了适合我的 hacky 脚本。您会注意到我使用它awk并且它可以很好地处理多行问题。只是据我所知,awk没有提供很多工具来操纵或解决这个短语,就像sed上面给出的例子一样。

# create backup of file
cp $FILE $FILE.bak

# delete previous .tmp file
if [ -f $FILE.tmp ]; then
    rm $FILE.tmp
fi

# if the expression is not in the paragraph, append it to $FILE.tmp
awk -v RS="" -v expr1="Host $COMPUTER" -v expr2="Match originalhost \
$COMPUTER" -v user="User $USER" \
'{ if (! (($0 ~ expr1 || $0 ~ expr2) && $0 ~ user)) print$0 "\n"}' \
$FILE >> $FILE.tmp

mv $FILE.tmp $FILE

我的问题空间

下面给出了$FILEfor$COMPUTER="compy"和中的一组匹配段落。$USER="harpo"人们可以想象其他计算机甚至同一计算机上的其他用户的条目(因此检查计算机和用户匹配)。

Match originalhost compy exec /usr/local/bin/superscript.sh
   HostName 192.168.0.101
   User harpo
   Port 22
   IdentityFile /home/harpo/.ssh/id_rsa

Host compy
   HostName 123.123.123.123
   User harpo
   Port 33
   IdentityFile /home/harpo/.ssh/id_rsa

答案1

如何在每个段落之间放置一个注释符号,并确保文件中不存在其他注释符号。然后您可以使用awk并设置将整个段落作为单个记录RS="#"读取awk,您可以进行处理和检查,然后您可以在文件中随后或稍后输出(或不输出)您想要的内容、方式,或在文件末尾(使用 的awkEND 地址说明符)。

更新:awk文档告诉我,为了使这个答案起作用,没有理由要求注释符号不存在于文件的其他地方,因为的值RS可以是正则表达式!

相关内容