1

全部,

我正在尝试使用 sed(我对 ksh 很陌生)编写一个 KSH 脚本,该脚本从日志中提取此 SQL 查询,但我希望它忽略时间戳和后面的六个字符/空格。这是我到目前为止的代码......

cat file.log \
| sed -n '/---Query1/,/selected/p' \
| sed 's/^([0-9][0-9]:[0-9][0-9]:[0-9][0-9]??????)//g' \    # My problem
> newfile.log

===Input===

11:23:34 SQL> ---Query1    
11:23:34 SQL> select a.column1, b.column2, count(*)
11:23:34   2  from table1 a, table2 b
11:23:34   3  group by a.column1
11:23:34   4  order by 1, 2, 3;

a.column1   a.column2   count(*)
----------- ----------- ----------
foo         bar         32

1 row selected.


===Desired Output===

---Query1
select a.column1, b.column2, count(*)
from table1 a, table2 b
group by a.column1
order by 1, 2, 3;

a.column1   a.column2   count(*)
----------- ----------- ----------
foo         bar         32

1 row selected.

非常感谢您提供的任何帮助。

4

3 回答 3

2

“?” 在正则表达式中表示“前面的 RE 段出现零次或 1 次”,因此当您编写时:

[0-9]?

您是在说“一个数字出现零次或 1 次”。我怀疑你得到了“?”的意思。在 RE 中混淆了它在 shell globbing 中的含义,即“任何单个字符”。表示“任何单个字符”的 RE 元字符是“.”,而不是“?”。

所以我想当你写的时候:

sed 's/^([0-9][0-9]:[0-9][0-9]:[0-9][0-9]??????)//g'

你实际上打算写:

sed 's/^([0-9][0-9]:[0-9][0-9]:[0-9][0-9]......)//g'

您可以缩写为:

sed 's/^([0-9][0-9]:[0-9][0-9]:[0-9][0-9]??????)//g'

对于某些(例如 GNU)sed,您可以编写“.{6}”而不是 6 个显式的“.”。

请注意,您不需要“cat”,并且如果您将管道放在每行的末尾而不是下一行的开头,那么您也不需要转义反斜杠。您也不需要 RE 周围的括号,因为您从不反向引用或以其他方式使用它,例如:

sed -n '/---Query1/,/selected/p' file.log |
sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]......//g' > newfile.log
于 2013-05-06T18:47:48.670 回答
1

这可能对您有用(GNU sed):

 sed -r 's/^..:..:...{6}//' file
于 2013-05-06T19:15:13.057 回答
1

刚刚对您的示例数据进行了一些测试,它在这里工作:

 sed -r '/^[0-9][0-9]:[0-9][0-9]/{s/^.*SQL> *//;s/^[0-9:]* +[0-9]+ +(.)/\1/}' file
于 2013-05-06T17:29:19.147 回答