我正在寻找GNU sed
的解决方案,但是POSIX sed
没问题,awk
可以,但可能比必要的更复杂。我更喜欢sed,它应该很容易,但我被卡住了。看起来像一个单行可以做到这一点,不需要创建一个python / bash脚本或任何东西。
sed -i '218,226140d; 218i ...REMOVED...' psql.log
这会删除所需的行,但插入会丢失。如果我将插入移动到第217行,我得到:
sed -i '218,226140d; 217i ...REMOVED...' psql.log
结果:
┌────────────┬─────────────────────┬─────────────────┐
│ col_one │ col_two │ column_three │
├────────────┼─────────────────────┼─────────────────┤
│ CC00CBSNRY │ 553854451 │ 15003.44 │
│ CC00CBSNRY │ 1334177150 │ 5159.57 │
...REMOVED...
│ CC6XDSQGH2 │ 42385958605 │ [null] │ (line 217 in original file)
│ CC6XJ8YG5C │ 24661013005 │ [null] │ (line 226141 in original file)
│ CC6XJ9HGRG │ 44946564505 │ [null] │
│ CC6XMQW6SJ │ 34496719615 │ [null] │
└────────────┴─────────────────────┴─────────────────┘
我知道 - 这应该足够好了,但我很生气,我不能让这个简单的单行工作正常。我错过了什么?
我保留psql.log
文件作为我正在开发SQL代码的工作的参考。查看查询和结果的迭代非常有用。
问题是,有时我忘记限制输出,查询将生成100k +行的结果,这些结果不是一个有用的参考,我想从我的文件中删除它们,留下一个提醒我的注释查询输出已被删除。
匹配模式会很好,比如每个输出超过50行我可以压缩到前5行和最后5行。但是,我很容易标记我已经吹过的行号在文件中,所以我很高兴只使用sed删除N到M行,并在第N行插入消息...REMOVED...
。
这是一个示例日志文件,添加的注释在括号中。查询文本可以更改,列数可以是1到100或更多:
...
********* QUERY **********
select *
from table
where rnk <= 3
**************************
┌────────────┬─────────────────────┬─────────────────┐
│ col_one │ col_two │ column_three │
├────────────┼─────────────────────┼─────────────────┤
│ CC00CBSNRY │ 553854451 │ 15003.44 │
│ CC00CBSNRY │ 1334177150 │ 5159.57 │
│ CC6XDSQGH2 │ 42385958605 │ [null] │ (line 217)
│ CC6XF2SVWT │ 13182280615 │ [null] │
(many rows)
│ CC6XF2XWDT │ 995086081 │ [null] │
│ CC6XFX3TL1 │ 25195177405 │ [null] │
│ CC6XJ8YG5C │ 24661013005 │ [null] │ (line 226141)
│ CC6XJ9HGRG │ 44946564505 │ [null] │
│ CC6XMQW6SJ │ 34496719615 │ [null] │
└────────────┴─────────────────────┴─────────────────┘
(225926 rows)
********* QUERY **********
/* another query begins */
select * from table where X = 1 limit 20;
/* well done you remembered to limit the output */
**************************
...
查询文本应该都不受影响,并保留顶部/底部三行输出。添加了注释...REMOVED...
,删除了第218行到第226140行:
********* QUERY **********
select *
from table
where rnk <= 3
**************************
┌────────────┬─────────────────────┬─────────────────┐
│ col_one │ col_two │ column_three │
├────────────┼─────────────────────┼─────────────────┤
│ CC00CBSNRY │ 553854451 │ 15003.44 │
│ CC00CBSNRY │ 1334177150 │ 5159.57 │
│ CC6XDSQGH2 │ 42385958605 │ [null] │ (line 217 in original file)
...REMOVED...
│ CC6XJ8YG5C │ 24661013005 │ [null] │ (line 226141 in original file)
│ CC6XJ9HGRG │ 44946564505 │ [null] │
│ CC6XMQW6SJ │ 34496719615 │ [null] │
└────────────┴─────────────────────┴─────────────────┘
(225926 rows)
********* QUERY **********
(etc just like example above)
\pset border 2
┌
字符的解决方案是脆弱的,但确定答案 0 :(得分:2)
有一个例子'每个输出超过50行我可以压缩到前5行和后5'。
使用测试输入:
$ seq 160 | awk -vstart=10 -vmax=50 -vleft=5 '{if(NR < start) {print; next} {i++; if(i <= left || i > max - left){print}; if(i == left + 1){print "...REMOVED..."}if(i == max){i = 0}}}'
如果您将脚本放入文件中,请将其存储到squash.awk
BEGIN {
start=10;
max=50;
left=5;
}
{
if(NR < start) {
print;
next
}
i++;
if(i <= left || i > max - left) {
print
}
if(i == left + 1) {
print "...REMOVED...";
}
if(i == max) {
i = 0
}
}
进行测试:
$ seq 160 | awk -f squash.awk
start
是压缩线开始的行号。max
是最大行数(在您的示例中为50)。left
是max
首先和最后一行剩余的行数。if(NR < start) {print; next}
如果行号小于start
(在我们的例子中为10),我们只打印它们并转到下一行。
在这里你可以设置任何条件来跳过挤压。i++
它是行计数器增量。 if(i <= left || i > max - left){print}
如果行数小于5或更多,则max - 5
- 打印出来。if(i == left + 1){print "...REMOVED..."}
当我们开始跳过行时 - 输入“... REMOVED ...”消息if(i == max){i = 0}
如果行计数器达到max
,则将其归零答案 1 :(得分:1)
一个在awk中:
$ awk '
/^ └/ { # at the end marker
for(j=1;j<=6;j++) # output from the buffer b the wanted records
print b[j]
for(j=(i-2);j<=i;j++)
print b[j]
delete b # reset buffer
i=0 # and flag / counter
}
/^ ┌/ || i { # at the start marker or when flag up
b[++i]=$0 # gather records to buffer
next
} 1' file # print records which are not between the markers
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed -r '/\o342[^\n]*$/{:a;N;//ba;s/^(([^\n]*\n){6}).*((\n[^\n]*){5})$/\1 ... REMOVED ...\3/}' file
仅关注将始终包含八进制值342
的表数据。在模式空间中收集表格行,替换所需的值... REMOVED ...
并打印。所需字符串上方和下方的行数可在此处更改为6(标题+3行)和5(必需字符串+3行+表计数)。
要更改范围,请使用:
sed 'm,nc ... REMOVE ...' file # where m,n from and to line numbers
或:
sed -e 'ma ...REMOVE ...' -e 'm,nd' file
N.B。 d
命令终止以下任何命令。
答案 3 :(得分:0)
sed
手册页比初看起来更有帮助。 [addr]c
命令正是所需的(注意忽略c后的空格):
sed -i '218,226141c ...REMOVED...' psql.log
所以有已知行号的解决方案。
是否有人想提供不知道行号的通用解决方案?可能awk
可能是更好的工具,但也许sed
可以删除太长的输出。