最好使用awk和grep从上面的行中提取模式和某个字段

时间:2012-05-29 13:16:48

标签: unix awk grep

我有一个这样的文本文件:

********** time1 **********
line of text1
line of text1.1
line of text1.2
********** time2 **********
********** time3 **********
********** time4 **********
line of text2.1
line of text2.2
********** time5 **********
********** time6 **********
line of text3.1

我想提取文本行和时间(没有星星)高于它并将其存储在文件中。(时间下面没有任何文本行的时间必须被忽略)。我想用grep和awk做这个。 例如,上面代码的输出应为

time1 : line of text1
time1 : line of text1.1
time1 : line of text1.2
time4 : line of text2.1
time4 : line of text2.2
time6 : line of text3

我该怎么做?

7 个答案:

答案 0 :(得分:2)

这假设时间中没有空格,并且每个时间标记后只有一行(或零)文本。

awk '$1 ~ /\*+/ {prev = $2} $1 !~ /\*+/ {print prev, ":", $0}' inputfile

答案 1 :(得分:2)

在当时使用空格:

awk '/^[^*]+/ { gsub(/*/,"",x);printf x": "; print };{x=$0}' data.txt

答案 2 :(得分:1)

你可以使用vim

这样做
:%s_\*\+ \(YOUR TIME PATTERN\) \*\+\_.\(\[^*\].*\)$_\1 : \2_ | g_\*\+ YOUR TIME PATTERN \*\+_d

即搜索TIME PATTERN行并保存时间模式,如果未使用*启动,则保存下一行。然后从它们创建新行。然后删除剩余的TIME PATTERN行。

注意这假设时间模式行以*等结尾。

使用awk

awk '/\*+ YOUR TIME PATTERN \*+/ { time=gensub("\*+ (YOUR TIME PATTERN) \*+","\\1","g") }
     ! /\*+ YOUR TIME PATTERN \*+/ { print time " : " $0 }' INPUTFILE

还有其他方法可以做到。

答案 3 :(得分:1)

在awk中,请参阅:

#!/bin/bash

awk '
    BEGIN{
        t=0
    }
    {
        if ($0 ~ " time[0-9]+ ") {
            v=$2
            t=1
        }
        else if ($0 ~ "line of text") {
            if (t==1) {
                printf("%s : %s\n", v, $0)
            } else {
               t=0;
            }
        }
    }
' FILE

只需用您的文件名替换FILE

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed '/^\*\+ \S\+.*/!d;s/[ *]//g;$!N;/\n[^*]/!D;s/\n/ : /' file

说明:

  • 如果没有删除,请查找以*开头的行。 /^\*\+ \S\+.*/!d
  • 有时间表。删除*和空格(留出时间)。 s/[ *]//g
  • 获取下一行$!N
  • 检查第二行不以*开头,否则删除第一行/\n[^*]/!D
  • 获得预期的模式,将\n替换为间隔:并打印。 s/\n/ : /

答案 5 :(得分:0)

awk '{ if( $0 ~ /^\*+ time[0-9] \*+$/ ) { time = $2 } else { print time " : " $0 } }' file

答案 6 :(得分:0)

$ uniq -f 2 input-file | awk '{getline n; print $2 " : " n}'

如果您的时间戳中包含空格,请将参数更改为-f选项,以便uniq仅比较最终字符串*。例如,使用-f X,其中X-2是时间戳中的空格数。此外,如果时间戳中有空格,则awk将需要更改。这些都可以起作用:

$ uniq -f 3 input-file | awk -F '**********' '{getline n; print $2 " : " n}'
$ uniq -f 3 input-file | awk '{getline n; $1=""; $NF=""; print $0 ": " n }'