【问题标题】:bash/sed - adding multiple lines at specific location in filebash/sed - 在文件的特定位置添加多行
【发布时间】:2022-01-12 13:32:58
【问题描述】:

我想自动将新后端添加到配置文件中,但不知道该怎么做。文件的相关部分如下所示:

[backend]
backends = backend-1 backend-2
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3 

我正在寻找一个简单的解决方案来添加另一个具有特定 url 和密码的后端条目。

[backend-3]
url = https://adiffrentdomain.com
secret = 42349234238423424

同时将名称“backend-3”附加到“[backend]”部分的“backends =”行。

有没有办法通过一般的 sed 或 bash 脚本来完成这项工作?

感谢任何帮助或提示!

【问题讨论】:

  • url和secret的信息从哪里来?标准输入、文件等?
  • 因为这将在 bash 脚本中使用,所以它来自变量。该信息由脚本的用户在开头提供。
  • 脚本是否应该为自己找出后端编号?它添加的部分是否需要紧跟在其他后端之后(例如,在第一个后端之前或在文件末尾)?或者,脚本是否可以依赖所有后端部分在输入中组合在一起?关于[backend]部分的位置和原始内容,它可以依赖什么?
  • 您在 cmets 中提到建议的答案错误地将新的 backends-3 部分添加到文件末尾;我假设您的文件包含除 backends 数据之外的其他条目,在这种情况下,您应该使用其他数据的一些样本(对于输入和预期输出)更新问题,以便我们更好地了解新条目的位置是相对于文件中的其他数据插入的
  • 您能否确认编号为backends 的条目始终以1 开头并且编号中没有间隔(例如,您不能有backends-1 backends-5

标签: linux bash awk sed


【解决方案1】:

awk 用于任意新后端条目,newbackendnameurlsecret 是唯一提供的输入。只需将新后端添加到backends =-list 和一般[backend]-block 之后的相应块。

awk -vnewentry="newbackendname" -vurl="http://new.url" -vsecret="secret123" '
  #in backends= line: add new entry (at first position)
  #and set `add` marker
  /^backends =/{sub(/^backends = /,"&"newentry" ",$0) ; add=1}
  #marker exists and empty line (end of header block) is found:
  #print new entry and unset marker `add`
  add && /^$/{ print "\n["newentry"]"
               print "url = "url
               print "secret = "secret
               add=0}
  #print by default
  1' infile.txt

希望 cmets 可以让您轻松理解。使用此代码,您也可以通过 shell 变量将 url 和 secret 添加为 awk -vurl="$URL" -vsecret="$SECRET" -vnewentry="$NEWBACKEND" '...' infile.txt

【讨论】:

  • 这比我想象的要先进得多。当后端名称不通用时,有没有办法管理这个?作为旁注,新后端的名称也存储在变量中
  • 您的意思是后端名称是否类似于backends = b-1 x unsorted anyname?在这种情况下,我假设新条目可能 a) 刚刚添加到 backends = 列表的末尾,并且新块也可能直接出现在 [backend] 块之后?还是必须是最后一个区块? backends =-list 是否与以下相应块的顺序相同?也许您可以提供在所有 [backend-i] 条目之后开始新部分的关键字? (例如[general-options] 或其他。这可能有用
  • 你是对的。可以在 [backends] 块之后添加新部分。不一定要井井有条。没有特殊关键字,但我可以将它们重命名为 [be*customname*],因为它们不需要遵循任何方案,但似乎你不能在名称中使用特殊字符。
  • 嗯,这样就更简单了:现在只需将新块直接添加到通用块之后,并将条目添加到列表中。
  • 谢谢!这太棒了:) cmets 真的很有帮助。干杯,如果可以的话,我会花你一杯啤酒;)
【解决方案2】:

使用sed

$ sed '/backends =/s/$/ backend-3/;/^\[backend-2/{N;N;s|secret.*|&\n\n[backend-3] \
url = https://adifferentdomain.com \
secret = 42349234238423424|}' input_file
[backend]
backends = backend-1 backend-2 backend-3
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3

[backend-3]
url = https://adiffrentdomain.com
secret = 42349234238423424

如果输入来自变量,您可能希望使用双引号来扩展变量。例如;

sed "/backends =/s/$/ backend-3/;$a\\n[backend-3] \
url = $url_input \
secret = $secret_input" input_file

【讨论】:

  • 这适用于将后端添加到“后端=”行,但它只是将新的后端部分附加到文件的末尾
  • @pyte 请尝试编辑后的代码
【解决方案3】:

您可以尝试使用awk 的方法。它向以 backends 开头的行添加 backends 条目,并在 [backend][backend-x] 部分/strong> 块(在 connectionsperhost 之后)。
显然它依赖于后端的条目是否正确,因为它不单独计算 [backend] 部分。

url="www.domain.com"
s=9283283h4923h42934

% awk -v url="${url}" -v s="${s}" '/^backends/{x=NF-1; $0=$0" backend-"x} 
    /^connectionsperhost/{ print; $0="\n[backend-"x"]\nurl = "url"\nsecret = "s} 
    {print}' file
[backend]
backends = backend-1 backend-2 backend-3
timeout = 10
connectionsperhost = 100

[backend-3]
url = www.domain.com
secret = 9283283h4923h42934

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3

数据

cat file
[backend]
backends = backend-1 backend-2
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3 

【讨论】:

  • 这与发布的其他解决方案具有相同的问题。我在文件末尾附加了新的部分。
  • @pyte 改变了定位。
  • @pyte,将预期的输出添加到问题中;到目前为止,我不知道你想在哪里添加新的后端
猜你喜欢
  • 2020-10-26
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 2020-03-06
相关资源
最近更新 更多