【问题标题】:find first character after a given string查找给定字符串后的第一个字符
【发布时间】:2017-05-09 14:35:34
【问题描述】:

我正在编写一个 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 行中的 ] 转换为逗号,并在第 40 行下方插入 {:foo, "~> 1.0"}]。我假设您可以使用 defp deps do 作为 sed 中的标记或awk 表达式,然后定位后面的第一个 ]

最好的方法是什么?

【问题讨论】:

  • 是的,你有一个逻辑开始......这里有一些东西可以帮助你尝试命令stackoverflow.com/questions/38972736/…,然后询问你是否卡住了
  • @Sundeep 事实证明,这是配置文件中唯一出现}] 模式的地方,所以一个简单的sed 无需环顾四周即可。但是,这超出了我最初的问题和意图。 @sat 有一个可靠的答案(尽管对于 GNU sed,OSX sed 不同)...如果您可以在 awk 中提供更通用的解决方案,我会将其标记为正确的。

标签: regex awk sed grep phoenix-framework


【解决方案1】:

你可以使用这个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
    

【讨论】:

  • 我喜欢这里的逻辑。我一直收到这个错误:sed: 1: "/^defp deps do/{:loop; ...": unexpected EOF (pending }'s).
  • @MarkKaravan,试试这个:sed '/^defp deps do/{:loop; /]$/{s/]$/,\n {:foo, "~> 1.0"}]/g;b;}; n; b loop;}' file
  • 同样的错误...也许是版本问题?我在 OS X 10.11.6 上使用 #/bin/bash...遗憾的是它不会让我检查 sed 的版本
  • 更新:它是 OSX,它以不同的方式实现 sed。
【解决方案2】:

我会使用这个命令:

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 打印回捕获的部分。然后添加换行符、必要的空格、新配置和括号。 IE。正是您在这里看到的。

【讨论】:

  • 很有用,可以完成工作。不过,我想要一些与最后一个依赖项无关的东西。此外,似乎 OSX(我正在使用)实现 sed 与其他系统不同......我的版本看起来像这样:sed -i '' 's/\({:cowboy.*\)\]/\1,\ {:foo, "~> 1.0"}]/g' config.txt....(在评论中看不到,但它是一个正确的换行符,不是\n)
猜你喜欢
  • 2018-01-19
  • 2017-09-22
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-12
  • 2014-09-19
  • 2022-11-01
相关资源
最近更新 更多