我正在尝试编写一个脚本来自动更新我的.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
我的问题空间
下面给出了$FILE
for$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
,您可以进行处理和检查,然后您可以在文件中随后或稍后输出(或不输出)您想要的内容、方式,或在文件末尾(使用 的awk
END 地址说明符)。
更新:awk
文档告诉我,为了使这个答案起作用,没有理由要求注释符号不存在于文件的其他地方,因为的值RS
可以是正则表达式!