在 bash 中删除多余行的最快方法,或者如果字符串是 # 则删除最后一行

在 bash 中删除多余行的最快方法,或者如果字符串是 # 则删除最后一行

寻找一种优雅的方法,在脚本结束时bash清理生成的文件,如果:

  1. 要删除的行下面的行的第一个字符是# 或者
  2. #是文件中最后一行的第一个字符。

文件可能看起来像这样(参考行号在[]但在不是在文件本身中):

[1] # foo
[2] bar1
[3] bar2
[4] bar3
[5] # foob
[6] #ar
[7] ar1
[8] ar2
[9] ar3
[10] #

在上面的示例中,我想删除第 5 行和第 10 行。我不希望任何以 开头的行后面#跟着以 开头的行,#并且我不希望文件的最后一行以 开头#

编辑:预期输出:

[1] # foo
[2] bar1
[3] bar2
[4] bar3
[5] #ar
[6] ar1
[7] ar2
[8] ar3

bash边走边教自己极好的sedawk语法混淆,但我怀疑它们就是这里的答案。

答案1

思考你想要的是

sed -e '${/^#/d}' -e '$!N;/^#.*\n#/D' -e 'P;D' file
  • ${/^#/d}地址最后一行$;如果匹配^#则删除它

  • $!N...P;D维持滚动的两行缓冲区

  • /^#.*\n#/D#如果模式开头和换行符后面都有 a ,则删除到换行符并开始新的循环

答案2

sed您的要求可以如图所示进行编码。

sed -e '
  /^#/!b
  $d;N
  /\n#/D
' file
  • 任何不感兴趣的行都会被发送到标准输出,这意味着打印:/^#/!b

  • 有趣的一行是以 a 开头的#

  • 最后一行恰好有趣的被删除:$d

  • 请注意,无意义的行不能出现在第二个 sed 代码行中。

  • 如果感兴趣的行不是文件的最后一行,我们将下一行附加到它:N

  • 如果下一行也很有趣,请删除上一行并使用现有模式空间转到 sed 脚本的顶部: /\n#/D

您应该参阅 sed 手册以获取有关所使用的各种 sed 命令的详细信息。

答案3

您可以使用sed多线技术

sed -E 'N;s/(^#.*)(#.*)/\2/;${s/(.*)(#.*)/\1/}' file

N命令将 anewline和下一行追加到模式空间。

对于带有模式的行^#.*#.*删除第一行。

${}对于最后一行,检查模式是否.*#.*匹配,删除最后一部分。

答案4

sed -n '/^#/{:a;h;n;//b a;H;g;};p' file

选项-n禁用自动打印,行将通过p操作打印。/^#/{ ... }– 在以 开头的行上#,执行一组操作。:a...b a设置一个循环,在该循环中:

  • h用模式空间替换保持空间(即将当前行保存到缓冲区)。
  • n将下一行输入读入模式空间(或退出,没有更多输入)。
  • //b a–如果模式空间匹配则b牧场到。在 中,空正则表达式是 的简写。:a/^#/sedapply the last used regex

循环完成后:H;g– 将当前模式空间追加到保持空间,并将模式空间替换为保持空间。p最后打印循环的结果以及所有其他非行#

#结果:仅打印任何一组行中的最后一行,#末尾之前不打印任何行。

# foo
bar1
bar2
bar3
#ar
ar1
ar2
ar3

相关内容