我有一个这样的文本文件:
********** 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
我该怎么做?
答案 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 }'