我得到了一个包含以下内容的文件,并希望删除最后一个逗号(在本例中,是“c”和“f”后面的逗号)。
heading1( a, b, c, ); some more text heading2( d, e, f, );
我可以使用sed,awk等,但是我不能使用带-z参数的sed,因为我使用的是旧版本的实用程序。所以sed -zi 's/,\n);/\n);/g' $file是不可能的。任何帮助将不胜感激。谢谢
sed
awk
-z
sed -zi 's/,\n);/\n);/g' $file
pgky5nke1#
这在您的sed版本中可能有效,但也可能无效。
sed 'x;1d;G;/;$/s/,//;$!s/\n.*//' $file
粗略翻译:“将此行与保留空格交换。如果这是第一行,则不再对它执行其他操作。将保留空格追加到缓冲区中的该行(这样您就可以看到最后一行和当前行)。如果您所看到的内容以分号结尾,请删除逗号。如果您不在文件的最后一行,请删除您所看到的两行内容中的第二行。(即当前行,我们将在看到下一行后处理)。”
7xzttuei2#
使用awk、RS="^$"读入整个文件,使用regex替换部分文本:
RS="^$"
$ awk -v RS=^$ '{gsub(/,\n\);/,"\n);")}1' file
部分输出:
heading1( a, b, c ); ...
xxe27gdn3#
在所示的输入上,这应该可以与GNU sed和BSD sed一起使用:
sed -e ':a' -e '/,\n);$/!{N' -e 'ba' -e '}' -e 's/,\n);$/\n);/' file.txt
我们将模式空间中的行连接起来,直到它以,\n);结束。然后我们删除逗号,打印(默认设置),并以新的一行重新开始循环。使用GNU sed的更简单、更可读的版本(您没有):
,\n);
sed ':a;/,\n);$/!{N;ba};s/,\n);$/\n);/' file.txt
gwbalxhn4#
使用awk:
awk ' $0==");" {sub(/,$/, "", l)} FNR!=1 {print l} {l=$0} END {print l}'
lrpiutwd5#
这可能对你有用(GNU sed):
sed '/,$/{N;/);$/Ms/,$//M;P;D}' file
如果一行以逗号结尾,则提取下一行;如果该行以);结尾,则删除逗号。否则,如果下一行与上面的不匹配,则打印/删除第一行并重复。
);
s6fujrry6#
使用sed大致有两种方法:1.在图案空间中保留多条线;或1.将上一行保留在保留空间中。仅使用模式空间意味着非常简洁的版本:
sed 'N; s/,[[:space:]]*\n*[[:space:]]*)/)/; P; D'
这依赖于模式空间能够容纳多行,并且能够将换行符与\n匹配。不是所有的sed版本都能做到这一点,但GNU sed可以。这还依赖于N、P和D的隐式行为,这些隐式行为会随着输入结束的时间而改变。将其展开为每行一个命令,得到:
\n
N
P
D
sed ' N s/,[[:space:]]*\n*[[:space:]]*)/)/ P D '
如果只有POSIX版本的sed可用,则还需要使用hold空格。在这种情况下,当您在模式空间中看到)时,您可以编辑hold空格中的行以删除逗号:
)
sed '1 { h; d; }; /^)/ { x; s/,[[:space:]]*$//; x; }; x; $ { p; x; s/,$//; }'
展开我们得到:
sed ' 1 { h d } /^)/ { x s/,[[:space:]]*$// x } x $ { p x s/,[[:space:]]*$// } '
打破这一点:接下来是一个“sed脚本”;因此只需在它前后加上“”并在它前面加上“sed”:
sed '
首先,无条件地将第一行从模式空间复制到保留空间,然后删除模式空间(强制跳到下一行)对于以')'开头的每一行,交换模式空格并保留空格(这样您现在在模式空格中有了上一行),删除尾部逗号(如果有),然后再交换回来:
/^)/ { x s/,[[:space:]]*$// x }
现在用保留空间交换模式空间,这样保留空间现在保留 * 当前 * 行,模式空间保留前一行。
x
通常情况下,当到达脚本末尾时,模式空间的内容将被发送到输出,但是我们首先还要处理一个案例。在最后一行,打印前一行,然后交换以检索最后一行,然后(因为我们到达了脚本的结尾)也打印它。如果您不想这样做,可以删除下面的s命令。
s
$ { p x s/,[[:space:]]*$// }
在到达sed脚本的末尾时,将打印模式空间;所以结尾没有“p”。如前所述,请从头开始关闭报价。
'
6条答案
按热度按时间pgky5nke1#
这在您的sed版本中可能有效,但也可能无效。
粗略翻译:“将此行与保留空格交换。如果这是第一行,则不再对它执行其他操作。将保留空格追加到缓冲区中的该行(这样您就可以看到最后一行和当前行)。如果您所看到的内容以分号结尾,请删除逗号。如果您不在文件的最后一行,请删除您所看到的两行内容中的第二行。(即当前行,我们将在看到下一行后处理)。”
7xzttuei2#
使用awk、
RS="^$"
读入整个文件,使用regex替换部分文本:部分输出:
xxe27gdn3#
在所示的输入上,这应该可以与GNU sed和BSD sed一起使用:
我们将模式空间中的行连接起来,直到它以
,\n);
结束。然后我们删除逗号,打印(默认设置),并以新的一行重新开始循环。使用GNU sed的更简单、更可读的版本(您没有):
gwbalxhn4#
使用
awk
:lrpiutwd5#
这可能对你有用(GNU sed):
如果一行以逗号结尾,则提取下一行;如果该行以
);
结尾,则删除逗号。否则,如果下一行与上面的不匹配,则打印/删除第一行并重复。
s6fujrry6#
使用
sed
大致有两种方法:1.在图案空间中保留多条线;或
1.将上一行保留在保留空间中。
仅使用模式空间意味着非常简洁的版本:
这依赖于模式空间能够容纳多行,并且能够将换行符与
\n
匹配。不是所有的sed
版本都能做到这一点,但GNUsed
可以。这还依赖于
N
、P
和D
的隐式行为,这些隐式行为会随着输入结束的时间而改变。将其展开为每行一个命令,得到:
如果只有POSIX版本的
sed
可用,则还需要使用hold空格。在这种情况下,当您在模式空间中看到)
时,您可以编辑hold空格中的行以删除逗号:展开我们得到:
打破这一点:接下来是一个“sed脚本”;因此只需在它前后加上“”并在它前面加上“sed”:
首先,无条件地将第一行从模式空间复制到保留空间,然后删除模式空间(强制跳到下一行)
对于以')'开头的每一行,交换模式空格并保留空格(这样您现在在模式空格中有了上一行),删除尾部逗号(如果有),然后再交换回来:
现在用保留空间交换模式空间,这样保留空间现在保留 * 当前 * 行,模式空间保留前一行。
通常情况下,当到达脚本末尾时,模式空间的内容将被发送到输出,但是我们首先还要处理一个案例。
在最后一行,打印前一行,然后交换以检索最后一行,然后(因为我们到达了脚本的结尾)也打印它。如果您不想这样做,可以删除下面的
s
命令。在到达sed脚本的末尾时,将打印模式空间;所以结尾没有“p”。
如前所述,请从头开始关闭报价。