我有一个大文本文件,其中包含嵌入句子中的概率。我想只提取那些概率和它们之前的文本。实施例
输入:
not interesting
foo is 1 in 1,200 and test is 1 in 3.4 not interesting
something else is 1 in 2.5, things are 1 in 10
also not interesting
通缉输出:
foo is 1/1,200
and test is 1/3.4
something else is 1/2.5,
things are 1/10
到目前为止我所拥有的:
$ sed -nr ':a s|(.*) 1 in ([0-9.,]+)|\1 1/\2\n|;tx;by; :x h;ba; :y g;/^$/d; p' input
foo is 1/1,200
and test is 1/3.4
not interesting
something else is 1/2.5,
things are 1/10
something else is 1/2.5,
things are 1/10
这个漂亮的代码在匹配时重复分割行,并尝试仅在匹配时打印它。我的代码的问题似乎是在一行完成后没有清除保留空间。
一般问题是sed不能进行非贪婪匹配,我的分隔符可以是任何东西。
我想用不同语言的解决方案是可以的,但是如果在sed中可行的话,我现在有点好奇吗?
答案 0 :(得分:4)
这可能适合你(GNU sed):
sed -r 's/([0-9]) in ([0-9]\S*\s*)/\1\/\2\n/;/[0-9]\/[0-9]/P;D' file
这将替换一些数字,后跟空格,后跟in
后跟一个空格,后跟一个以数字开头的标记,后跟一个可能的空格,第一个数字后跟/
,后跟第二个数字令牌以数字开头,后跟新行。如果以下行包含一个数字,后跟一个/`后跟一个数字,则打印它然后将其删除,如果模式空间中有任何其他内容重复。
答案 1 :(得分:4)
sed用于单个行上的简单替换,即全部。有趣的是,使用awk:
$ cat tst.awk
{
while ( match($0,/\s*([^0-9]+)([0-9]+)[^0-9]+([0-9,.]+)/,a) ) {
print a[1] a[2] "/" a[3]
$0 = substr($0,RSTART+RLENGTH)
}
}
$ awk -f tst.awk file
foo is 1/1,200
and test is 1/3.4
something else is 1/2.5,
things are 1/10
以上使用GNU awk作为match()
的第3个arg和\s
的{{1}}简写。
答案 2 :(得分:2)
是的,sed可以做到,虽然它不是这项工作的最佳工具。我的尝试是搜索所有number in number
模式,并在每个模式后添加换行符。然后删除尾随文本(后面没有换行符),删除前导空格并打印:
sed -nr '/([0-9]+) in ([0-9,.]+)/ { s//\1\/\2\n/g; s/\n[ ]*/\n/g; s/\n[^\n]*$//; p }' file
它产生:
foo is 1/1,200
and test is 1/3.4
something else is 1/2.5,
things are 1/10