如何 search/replace 与 sed/awk 内联?

How to search/replace a single inline with sed/awk?

我有很多文件,我只想编辑那些以 private.

开头的行

它的原理我要

gawk '/private/{gsub(/\//, "_"); gsub(/-/, "_"); print}' filename

但这只会打印出文件的修改部分,而不是所有内容。

问题

GNU awk 从 4.1.0 开始有原地能力。
你应该把 print 放在 reg 匹配块之外。
试试这个:

gawk '/^private/{gsub(/[/-]/, "_");} 1' filename

或者,确保备份文件:

gawk -i inplace '/^private/{gsub(/[/-]/, "_");} 1' filename

您忘记了 ^ 来表示 start,您需要它来更改以 private 开头的行,否则所有包含 private 的行都将被修改。
是的,您可以将两个 gsub 组合成一个。

执行相同操作的 sed 命令是:

sed '/^private/{s/[/-]/_/g;}' filename

测试完成后添加 -i 选项。

只需将最终打印移到过滤后的图案之外。例如:

gawk '/private/{gsub(/\//, "_"); gsub(/-/, "_")} {print}' 

通常,简化为:

gawk '/private/{gsub(/\//, "_"); gsub(/-/, "_")}1' 

您真的,真的,真的(强调“真的”)不想使用 sed -i 之类的东西来“就地”编辑文件。 (我将“就地”放在引号中,因为 gnu 的 sed 不会就地编辑文件,而是创建具有相同名称的新文件。)这样做会导致数据损坏,如果你有很多文件,你不想冒那个风险。只需将文件写入新目录树即可。这将使恢复变得更加简单。

例如:

d=backup/$(dirname "$filename")
mkdir -p "$d"
awk '...' "$filename" > "$d/$filename"

考虑一下您是否使用了类似 -i 的东西,它将备份文件放在相同的目录结构中。如果您正在批量修改文件并且该过程中途停止,您如何恢复?如果您将输出放入单独的树中,则恢复很简单。您的原始文件未受影响且是原始文件,如果您的过滤过程过早或无意中多次终止,也无需担心 运行。 sed -i 是人类的瘟疫,永远不应该使用。不要传播瘟疫。