直接修改现有文件以将“foo”替换为“bar”仅用于包含“baz”的行

jas*_*min 3 text-processing regular-expression

我有一个 food.txt 文件如下:-

mangoes|foo|faa  
oranges|foo|faa  
chocolates|foo|baz  
Run Code Online (Sandbox Code Playgroud)

如果条件 baz 满足,我试图用bar替换foo。(想在这里使用正则表达式 b*z ) 目前使用下面的 sed 命令,但这不会直接修改现有文件。我也不能使用正则表达式 (b*z)。

sed '/baz/s/foo/bar/g' food.txt
Run Code Online (Sandbox Code Playgroud)

请建议一种除“sed”之外的方法来直接修改现有文件。

PS:我试过了,sed -i但我想使用一些其他命令而不是 sed。
我正在使用 mobaxterm(操作系统 - Windows)

Kus*_*nda 7

我认为sed在这种情况下使用没有任何问题。这是完成这项工作的正确工具。

您的命令运行良好(在给定的数据上):

$ sed '/baz/s/foo/bar/g' food.txt
mangoes|foo|faa
oranges|foo|faa
chocolates|bar|baz
Run Code Online (Sandbox Code Playgroud)

使用正则表达式匹配任何以行|b尾开头和结尾的字符串z(而不是行中的baz任何地方):

$ sed '/|b.*z$/s/foo/bar/g' food.txt
mangoes|foo|faa
oranges|foo|faa
chocolates|bar|baz
Run Code Online (Sandbox Code Playgroud)

要对文件进行更改(使用 GNU sed):

$ sed -i '/|b.*z$/s/foo/bar/g' food.txt
Run Code Online (Sandbox Code Playgroud)

或(有任何sed实现):

$ sed '/|b.*z$/s/foo/bar/g' food.txt >tmpfile && mv tmpfile food.txt
Run Code Online (Sandbox Code Playgroud)

  • @terdon 感谢您的编辑。我没有使用 `sed -i` 的原因是它在 GNU 和 BSD `sed` 之间的工作方式非常不同。只是说 `sed -i script` 将使用 `script` 作为 BSD `sed` 的备份后缀。做 `sed ... && mv` 更安全,更便携。 (2认同)

hee*_*ayl 5

awk与以下一起使用gsub()

awk '/baz$/ {gsub("foo", "bar")};1' food.txt
Run Code Online (Sandbox Code Playgroud)
  • /baz$/如果需要,可以使用任何正则表达式模式来匹配而不是,

  • 如果模式匹配,则gsub()替换所需的字符串


对于内部编辑,最新版本的 GNU awk(>=4.1.0) 具有就地修改选项:

awk -i inplace '/baz$/ {gsub("foo", "bar")};1' food.txt
Run Code Online (Sandbox Code Playgroud)

否则,您可以使用spongeGNUmoreutils或使用临时文件:

awk '/baz$/ {gsub("foo", "bar")};1' food.txt >temp_food.txt && \
      mv temp_food.txt food.txt
Run Code Online (Sandbox Code Playgroud)

例子:

$ cat file.txt
mangoes|foo|faa
oranges|foo|faa
chocolates|foo|baz

$ awk '/baz$/ {gsub("foo", "bar")};1' file.txt
mangoes|foo|faa
oranges|foo|faa
chocolates|bar|baz
Run Code Online (Sandbox Code Playgroud)