找到给定字符串后的第一个字符

问题描述:

我正在编写一个bash脚本来安装Phoenix应用程序。我想添加依赖到我的配置文件的deps部分而不依赖行号。找到给定字符串后的第一个字符

31 # Type `mix help deps` for examples and options. 
32 defp deps do 
33 [{:phoenix, "~> 1.2.1"}, 
34  {:phoenix_pubsub, "~> 1.0"}, 
35  {:phoenix_ecto, "~> 3.0"}, 
36  {:postgrex, ">= 0.0.0"}, 
37  {:phoenix_html, "~> 2.6"}, 
38  {:phoenix_live_reload, "~> 1.0", only: :dev}, 
39  {:gettext, "~> 0.11"}, 
40  {:cowboy, "~> 1.0"}] 
41 end 

在这种情况下,我想打开]在管线40到逗号,并插入{:foo, "~> 1.0"}]下面线40我假设你可以在SED或AWK表达式中使用defp deps do作为标记,然后定位后面的第一个]

这样做的最好方法是什么?

+1

烨,你必须先从逻辑......这里的有些东西可以帮助你尝试命令https:// *。com/questions/38972736/how-to-select-lines-between-two-patterns然后询问你是否被卡住 – Sundeep

+0

@Sundeep事实证明,这是配置文件中唯一出现的模式'}]存在,所以一个简单的'sed'没有看看周围的作品。但是,这超出了我原来的问题和意图。 @sat有一个可靠的答案(尽管一个用于GNU sed,OSX sed是不同的)...如果你能在awk中提供更通用的解决方案,我会将其标记为正确的。 –

您可以使用此sed

sed '/^defp deps do/{:loop; /]$/{s/]$/,\n {:foo, "~> 1.0"}]/g;b}; n; b loop;}' file 

测试:

$ sed '/^defp deps do/{:loop; /]$/{s/]$/,\n {:foo, "~> 1.0"}]/g;b}; n; b loop;}' file 
# Type `mix help deps` for examples and options. 
defp deps do 
    [{:phoenix, "~> 1.2.1"}, 
    {:phoenix_pubsub, "~> 1.0"}, 
    {:phoenix_ecto, "~> 3.0"}, 
    {:postgrex, ">= 0.0.0"}, 
    {:phoenix_html, "~> 2.6"}, 
    {:phoenix_live_reload, "~> 1.0", only: :dev}, 
    {:gettext, "~> 0.11"}, 
    {:cowboy, "~> 1.0"}, 
    {:foo, "~> 1.0"}] 
end 

更新:(对于OSX

  1. 将此保存到file.sed
#!/bin/sed 
/^defp deps do/ { 
    :loop 
    /]$/ { 
     s/]$/,\n {:foo, "~> 1.0"}]/g 
     b 
    } 
    n 
    b loop 
} 
  1. 像这样运行

    $ sed -f file.sed inputfile.txt 
    
开始=>
+0

我喜欢这里的逻辑。尽管我一直收到这个错误:'sed:1:“/^defp deps do/{:loop; ...”:意外的EOF(正在等待)')。 –

+0

@MarkKaravan,试试这个:'sed'/^defp deps do/{:loop; /] $/{s /] $ /,\ n {:foo,“〜> 1.0”}]/g; b;}; N; b loop;}'file' – sat

+0

同样的错误...也许它是一个版本的东西?我在'OS X 10.11.6'上使用'#/ bin/bash' ...不幸的是,它不会让我检查sed的版本 –

我会用这个命令去:

sed -i config.txt -e 's/\({:cowboy.*\)\]/\1,\n {:foo, "~> 1.0"}]/g' 

说明:

  • sed -i <filename>编辑就地文件。在你运行这个之前,你可以试试cat filename | sed ...只是为了确保你做你想做的事情。
  • sed -e ...运行表达式
  • s/.../.../g是sed中的替换运算符。它将第一对斜杠中的东西替换为第二对斜杠中的其他东西。
  • /\(:cowboy.*\)\] - 它匹配包含{:cowboy并以]结尾的行。它捕捉所有内容,除了右括号]。我希望这只匹配第40行。我不知道你的完整文件。
  • 替换\1,\n {:foo, "~> 1.0"}]首先用\1打印捕获的部分。然后添加新行,必要空格,新配置和括号。即正是你在这里看到的。
+0

有用并完成工作。尽管如此,我想要一些不依赖于最后依赖的东西。此外,它似乎像OSX(我正在使用)实现sed与其他系统不同......我的版本看起来像这样: 'sed -i''s/\({:cowboy。* \)\]/\ 1,\ {:foo,“〜> 1.0”}]/g'config.txt' ....(在评论中看不到,但它是一个正确的换行符,而不是\ n) –