从每个块中的最后一个元素中删除逗号
Remove comma from last element in each block
我有一个包含以下内容的文件,我想删除最后一个逗号(在本例中,是 'c' 和 'f' 之后的逗号)。
heading1(
a,
b,
c,
);
some more text
heading2(
d,
e,
f,
);
这必须使用 bash 而不是 Perl 或 Python 等,因为我的目标系统上没有安装这些。我可以使用 sed
、awk
等,但我不能将 sed 与 -z
参数一起使用,因为我使用的是该实用程序的旧版本。
所以 sed -zi 's/,\n);/\n);/g' $file
关闭了 table。
如有任何帮助,我们将不胜感激。谢谢
这可能适用于您的 sed 版本。然后又可能不会。
sed 'x;1d;G;/;$/s/,//;$!s/\n.*//' $file
粗略翻译:“将此行与保留 space 交换。如果这是第一行,则不再使用它。将保留 space 附加到缓冲区中的行(因此你正在查看最后一行和当前行。如果你的内容以分号结尾,请删除逗号。如果你不在文件的最后一行,请删除你拥有的两行中的第二行(即当前行,我们将在看到下一行后处理)。"
使用sed
大致有两种方法:
- 在模式中保留多行space;或
- 保留前一行 space。
仅使用模式 space 意味着非常简洁的版本:
sed 'N; s/,\n*)/)/; P; D'
这依赖于模式 space 能够容纳多行,并且能够将换行符与 \n
相匹配。并非所有 sed
版本都可以做到这一点,但 GNU sed
可以。
这也依赖于 N
、P
和 D
的隐式行为,这些行为会根据达到 end-of-input 的时间而变化。阅读 man sed
了解详细信息。
将其展开为每行一个命令得到:
sed '
N
s/,\n*)/)/
P
D
'
如果您只有 sed
的 POSIX 版本可用,您还需要使用保留 space。在这种情况下,想法是当您在模式 space 中看到 )
时,您编辑保留 space 中的行以删除逗号:
sed '1 { h; d; }; /^)/ { x; s/,$//; x; }; x; $ { p; x; s/,$//; }'
展开我们得到:
sed '
1 {
h
d
}
/^)/ {
x
s/,$//
x
}
x
$ {
p
x
s/,$//
}
'
分解:接下来是“sed 脚本”;所以只需在它周围加上''并在它前面加上“sed”:
sed '
首先无条件地将第一行从模式 space 复制到保留 space,然后删除模式 space(强制跳到下一行)
1 {
h
d
}
对于以 ')' 开头的每一行,交换模式 space 并按住 space(所以你现在在模式 space 中有前一行),删除尾随逗号(如果有),然后再次换回:
/^)/ {
x
s/,$//
x
}
现在将模式 space 与保持 space 交换,因此保持 space 现在保持 当前 线和模式 space 保留上一行。
x
通常模式 space 的内容会在到达脚本末尾时发送到输出,但我们还有一个情况需要先处理。
在最后一行,打印上一行,然后交换以检索最后一行,然后(因为我们到达 script0 的末尾也打印它。此代码还将从最后一行删除尾随逗号,但这是可选的;如果您不需要,可以将其删除。
$ {
p
x
s/,$//
}
到达 sed 脚本末尾时,将打印模式 space;所以最后没有“p”。
如前所述,从头开始引用。
'
注意:
如果您需要向前扫描多行,而不是“x”交换一行,请使用“H;g”附加到 hold space,然后将 hold space 复制到模式space,然后是“P;D”打印并删除第一个换行符。 (H、P 和 D 是 GNU 扩展。)
这应该在显示的输入上与 GNU sed 和 BSD sed 一起工作:
sed -e ':a' -e '/,\n);$/!{N' -e 'ba' -e '}' -e 's/,\n);$/\n);/' file.txt
我们连接模式 space 中的行,直到它以 ,\n);
结束。然后我们删除逗号,打印(默认)并用新行重新开始循环。
带有 GNU sed 的更简单和更易读的版本(你没有):
sed ':a;/,\n);$/!{N;ba};s/,\n);$/\n);/' file.txt
使用awk
:
awk '
[=10=]==");" {sub(/,$/, "", l)}
FNR!=1 {print l}
{l=[=10=]}
END {print l}'
使用 awk,RS="^$"
读入整个文件并用正则表达式替换部分文本:
$ awk -v RS=^$ '{gsub(/,\n\);/,"\n);")}1' file
一些输出:
heading1(
a,
b,
c
);
...
这可能适合您 (GNU sed):
sed '/,$/{N;/);$/Ms/,$//M;P;D}' file
如果一行以逗号结尾,则获取下一行,如果以 );
结尾,则删除逗号。
否则,如果下一行与上面不匹配,print/delete第一行并重复。
我有一个包含以下内容的文件,我想删除最后一个逗号(在本例中,是 'c' 和 'f' 之后的逗号)。
heading1(
a,
b,
c,
);
some more text
heading2(
d,
e,
f,
);
这必须使用 bash 而不是 Perl 或 Python 等,因为我的目标系统上没有安装这些。我可以使用 sed
、awk
等,但我不能将 sed 与 -z
参数一起使用,因为我使用的是该实用程序的旧版本。
所以 sed -zi 's/,\n);/\n);/g' $file
关闭了 table。
如有任何帮助,我们将不胜感激。谢谢
这可能适用于您的 sed 版本。然后又可能不会。
sed 'x;1d;G;/;$/s/,//;$!s/\n.*//' $file
粗略翻译:“将此行与保留 space 交换。如果这是第一行,则不再使用它。将保留 space 附加到缓冲区中的行(因此你正在查看最后一行和当前行。如果你的内容以分号结尾,请删除逗号。如果你不在文件的最后一行,请删除你拥有的两行中的第二行(即当前行,我们将在看到下一行后处理)。"
使用sed
大致有两种方法:
- 在模式中保留多行space;或
- 保留前一行 space。
仅使用模式 space 意味着非常简洁的版本:
sed 'N; s/,\n*)/)/; P; D'
这依赖于模式 space 能够容纳多行,并且能够将换行符与 \n
相匹配。并非所有 sed
版本都可以做到这一点,但 GNU sed
可以。
这也依赖于 N
、P
和 D
的隐式行为,这些行为会根据达到 end-of-input 的时间而变化。阅读 man sed
了解详细信息。
将其展开为每行一个命令得到:
sed '
N
s/,\n*)/)/
P
D
'
如果您只有 sed
的 POSIX 版本可用,您还需要使用保留 space。在这种情况下,想法是当您在模式 space 中看到 )
时,您编辑保留 space 中的行以删除逗号:
sed '1 { h; d; }; /^)/ { x; s/,$//; x; }; x; $ { p; x; s/,$//; }'
展开我们得到:
sed '
1 {
h
d
}
/^)/ {
x
s/,$//
x
}
x
$ {
p
x
s/,$//
}
'
分解:接下来是“sed 脚本”;所以只需在它周围加上''并在它前面加上“sed”:
sed '
首先无条件地将第一行从模式 space 复制到保留 space,然后删除模式 space(强制跳到下一行)
1 {
h
d
}
对于以 ')' 开头的每一行,交换模式 space 并按住 space(所以你现在在模式 space 中有前一行),删除尾随逗号(如果有),然后再次换回:
/^)/ {
x
s/,$//
x
}
现在将模式 space 与保持 space 交换,因此保持 space 现在保持 当前 线和模式 space 保留上一行。
x
通常模式 space 的内容会在到达脚本末尾时发送到输出,但我们还有一个情况需要先处理。
在最后一行,打印上一行,然后交换以检索最后一行,然后(因为我们到达 script0 的末尾也打印它。此代码还将从最后一行删除尾随逗号,但这是可选的;如果您不需要,可以将其删除。
$ {
p
x
s/,$//
}
到达 sed 脚本末尾时,将打印模式 space;所以最后没有“p”。
如前所述,从头开始引用。
'
注意: 如果您需要向前扫描多行,而不是“x”交换一行,请使用“H;g”附加到 hold space,然后将 hold space 复制到模式space,然后是“P;D”打印并删除第一个换行符。 (H、P 和 D 是 GNU 扩展。)
这应该在显示的输入上与 GNU sed 和 BSD sed 一起工作:
sed -e ':a' -e '/,\n);$/!{N' -e 'ba' -e '}' -e 's/,\n);$/\n);/' file.txt
我们连接模式 space 中的行,直到它以 ,\n);
结束。然后我们删除逗号,打印(默认)并用新行重新开始循环。
带有 GNU sed 的更简单和更易读的版本(你没有):
sed ':a;/,\n);$/!{N;ba};s/,\n);$/\n);/' file.txt
使用awk
:
awk '
[=10=]==");" {sub(/,$/, "", l)}
FNR!=1 {print l}
{l=[=10=]}
END {print l}'
使用 awk,RS="^$"
读入整个文件并用正则表达式替换部分文本:
$ awk -v RS=^$ '{gsub(/,\n\);/,"\n);")}1' file
一些输出:
heading1(
a,
b,
c
);
...
这可能适合您 (GNU sed):
sed '/,$/{N;/);$/Ms/,$//M;P;D}' file
如果一行以逗号结尾,则获取下一行,如果以 );
结尾,则删除逗号。
否则,如果下一行与上面不匹配,print/delete第一行并重复。