我有一个文本文件,其中包含重复多次的行序列。例如:
param id: 0
value: 2
description: "hello"
param id: 1
value: 3
description: "world"
我想搬家描述多于价值并改变参数id到一个更高的值,例如参数id1 而不是 0。我想使用脚本来完成此操作。有人可以帮助我使用可以实现此目的的命令吗?
答案1
正如 @MelBursian 在评论中已经建议的那样,我也awk
赞成sed
.
awk '
BEGIN { OFS=FS=": " }
{
if ($1 == "param id") {
$2 += 1;
}
if ($1 == "value") {
val=$0; getline;
print; print val;
next;
}
print;
}
' file
答案2
这会将所有以“value:”开头的行与相应的下一行切换:
sed '/^value: /{N;s/^\(.*\)\n\(.*\)$/\2\n\1/}'
解释:
/^value: / { ... }
...
将仅对与正则表达式“^value:”匹配的行执行大括号中的命令(此处为 fake )N
将把下一行追加到模式空间。因此,从这里开始,我们可以对由换行符连接的两行进行操作。s/^\(.*\)\n\(.*\)$/\2\n\1/
将切换换行符之前的文本与换行符之后的文本。s/something/else/
是将“something”替换为“else”的替换命令^\(.*\)\n\(.*\)$
将匹配从模式空间开头到新行字符的任何文本并将其保存为表达式一,然后到模式空间末尾的所有其他字符将保存为表达式二\2\n\1
将表达式二后跟换行符,然后将表达式一作为替换
答案3
sed
极不建议使用 来增加值。它不是完成此类工作的正确工具。但如果必须如此sed
,这只适用于 GNU sed
。
sed -rn '/^param/{s/(.*)([0-9]+)/echo \1$((\2+1))/e;p;n;h;n;p;x;p;n;p}' file
-r
激活扩展正则表达式。-n
禁用sed
的自动打印。/^param/
搜索以模式 开头的行param
。s/(.*)([0-9]+)/echo \1$((\2+1))/e
现在在该行中进行搜索/替换。搜索 number([0-9]+)
并将其替换为echo \1$((\2+1))
,然后执行。e
ins///e
是在 shell 中执行匹配模式的修饰符。p;
然后打印更改后的行。n;
加载模式空间中的下一行(value
行)。h;
将该行复制到保留空间中。n;p;
加载下一行(该description
行)并打印它。x;
交换模式和保持空间。p;
打印该行。n;p
加载下一行(空行)并打印它。
带有示例输入的输出:
param id: 1
description: "hello"
value: 2
param id: 2
description: "world"
value: 3
答案4
使用 POSIX 可以最轻松地完成线路移动ex
;数字增量最容易用 来完成awk
。幸运的是,ex
允许您通过外部工具过滤特定行:
printf %s\\n 'g/description/m-2' 'g/param id/.!awk "++\$NF"' x | ex file
翻译成英语,第一个命令是“将所有包含单词‘description’的行移到一行”。
(那里有一个 2,因为,更字面地翻译,它是“将这些行移动到两行之后的点。”)
第二个是“通过 过滤包含‘param id’的每一行awk
。”
命令awk
是,“增加该行的最后一个字段(并打印该行,除非结果恰好为零。:)”
x
是“保存并退出”。