5

我正在尝试一段时间来解决这个问题,但到目前为止没有成功我有一个命令输出,我需要咀嚼它以使其适合进一步处理

我的文字是:

1/2 [3] (27/03/2012 19:32:54) word word word word 4/5

我需要的是只提取数字 1/2 [3] 4/5 所以它看起来:

1 2 3 4 5

所以,基本上我试图排除所有不是数字的字符,比如“/”、“[”、“]”等。我用 FS 尝试了 awk,尝试使用 regexp,但我的尝试都没有成功。

然后我会在其中添加一些内容,例如 first:1 second:2 third:3 .... 等等 请记住,我说的是一个包含很多 if 行的文件,如果行具有相同的结构,但我已经考虑过使用awk 对每一列求和

awk '{sum1+=$1 ; sum2+=$2 ;......etc} END {print "first:"sum1 " second:"sum2.....etc}'

但首先我只需要提取相关数字,“()”之间的日期可以完全省略,但它们也是数字,因此仅按数字过滤是不够的,因为它也会匹配它们

希望你能帮助我提前谢谢!

4

7 回答 7

5

这:sed -r 's/[(][^)]*[)]/ /g; s/[^0-9]+/ /g'应该工作。它进行了两次传递,首先删除带括号的表达式,然后用单个空格替换所有非数字运行。

于 2012-04-04T08:55:44.127 回答
2

你可以做类似的事情sed -e 's/(.*)//' -e 's/[^0-9]/ /g'。它会删除圆括号内的所有内容,而不是用空格替换所有非数字字符。要摆脱多余的空间,您可以将其提供给column -t

$ echo '1/2 [3] (27/03/2012 19:32:54) word word word word 4/5' | sed -e 's/(.*)//' -e 's/[^0-9]/ /g' | column -t
1  2  3  4  5
于 2012-04-04T08:52:29.443 回答
1

发射器:

@(collect)
@one/@two [@three] (@date @time) @(skip :greedy) @four/@five
@(filter :tonumber one two three four five)
@(end)
@(bind (first second third fourth fifth)
       @(mapcar (op apply +) (list one two three four five)))
@(output)
first:@first second:@second third:@third fourth:@fourth fifth:@fifth
@(end)

数据:

1/2 [3] (27/03/2012 19:32:54) word word word word 4/5
10/20 [30] (27/03/2012 19:32:54) word word 40/50

跑:

$ txr data.txr data.txt
first:11 second:22 third:33 fourth:44 fifth:55

容易添加一些错误检查:

@(collect)
@  (cases)
@one/@two [@three] (@date @time) @(skip :greedy) @four/@five
@  (or)
@line
@  (throw error `badly formatted line: @line`)
@  (end)
@  (filter :tonumber one two three four five)
@(end)
@(bind (first second third fourth fifth)
       @(mapcar (op apply +) (list one two three four five)))
@(output)
first:@first second:@second third:@third fourth:@fourth fifth:@fifth
@(end)

$ txr data.txr -
foo bar junk
txr: unhandled exception of type error:
txr: ("badly formatted line: foo bar junk")
Aborted

TXR 用于健壮的编程。有强类型,所以你不能仅仅因为字符串包含数字就将它们视为数字。变量必须在使用前绑定,因此拼写错误的变量不会默认为零或空白,而是会产生unbound variable <name> in <file>:<line>类型错误。使用大量特定上下文执行文本提取,以防止将一种格式的输入误解为另一种格式。

于 2012-04-04T19:52:48.420 回答
0

见下文,如果这是你想要的:

kent$  echo "1/2 [3] (27/03/2012 19:32:54) word word word word 4/5"|sed -r 's/\([^)]*\)//g; s/[^0-9]/ /g'
1 2  3                       4 5

如果你想让它看起来更好:

kent$  echo "1/2 [3] (27/03/2012 19:32:54) word word word word 4/5"|sed -r 's/\([^)]*\)//g; s/[^0-9]/ /g;s/ */ /g'
 1 2 3 4 5
于 2012-04-04T08:52:41.053 回答
0

这将为您提供提取的数字,不包括括号中的文本:

digits=$(echo '1/2 [3] (27/03/2012 19:32:54) word word word word 4/5' |\
       sed 's/(.*)//' | grep -o '[0-9][0-9]*')
echo $digits

或纯 sed 解决方案:

echo '1/2 [3] (27/03/2012 19:32:54) word word word word 4/5' |\
sed -e 's/(.*)//' -e 's/[^0-9]/ /g' -e 's/[ \t][ \t]*/ /g'

输出:

1 2 3 4 5
于 2012-04-04T08:53:26.230 回答
0
 awk '{ first+=gensub("^([0-9]+)/.*","\\1","g",$0)
        second+=gensub("^[0-9]+/([0-9]+) .*","\\1","g",$0)
        thirdl+=gensub("^[0-9]+/[0-9]+ \[([0-9]+)\].*","\\1","g",$0)
        fourth+=gensub("^.* ([0-9]+)/[0-9]+ *$","\\1","g",$0)
        fifth+=gensub("^.* [0-9]+/([0-9]+) *$","\\1","g",$0)
      }
      END { print "first: " first " second: " second " third: " third " fourth: " fourth " fifth: " fifth
      }

可能对你有用。

于 2012-04-04T08:57:05.110 回答
0

如果您设置了一个花哨的字段分隔符,则使用 awk 一次就足够了:斜线、空格、左括号或右括号中的任何一个都可以分隔一个字段:

awk -F '[][/ ]' '
  {s1+=$1; s2+=$2; s3+=$4; s4+=$(NF-1); s5+=$NF}
  END {printf("first:%d second:%d third:%d fourth:%d fifth:%d\n", s1, s2, s3, s4, s5)}
'
于 2012-04-04T11:12:04.563 回答