如果条件与awk匹配,则提取固定的行数

时间:2019-07-17 21:06:49

标签: bash awk

我一直在做一些研究,但是我认为这个问题非常特殊。 我想在条件匹配时从文件中提取固定数量的行。 假设文件看起来像这样:

19287.4342
23213.444443
Time = 0.1
333245.4324
0.2432421
98374532.3241
937463.41
82162.462
762542.16
452621.45
12.019288
Time = 0.2
93891.182
103837.3333
937382.32321
10383.32
163873.22
9821.001
83638.1209
443.232111
Time = 0.3
...

提取之后,我想每次i都得到一个文件。文件0.1.txt应该是:

937463.41
82162.462
762542.16
452621.45

还有0.2.txt

10383.32
163873.22
9821.001
83638.1209

所以我想在Time = i的每一行之后提取区间[4,7]内的行,其中i从0.1到10递增0.1。另一个观点是可以跳过Time = i之后的前3个数字,而跳过Time = i之前的最后3个数字。但是两者都会导致相同的结果。

我认为可以使用awkfor循环来完成此操作:

for i in {0.1..10..0.1}
do
awk -v t="${i}" '{if(($1=='Time') && ($3==t) print (here the interval I want);}' file > ${i}.txt
done

1 个答案:

答案 0 :(得分:1)

虽然您的问题很难理解,但似乎您要询问每行Time = 0.1,然后在这段时间到下一段之间的每一行,将由小写字符组成的每一行提取到文件名{ {1}}(源自0.1.txt行)

加上尝试的代码,很明显您对Time = 0.1字段有误解。您显示的输入文件中没有awk(第五字段)。最多只有3个字段(使用默认的以空格分隔的定界符)

好消息是,如果我理解您的要求正确,那么做您需要的事情就很容易。您只需要从$5开始的每一行捕获第三个字段,然后串联Time来创建文件名就可以了。然后只需匹配包含".txt"的每一行,然后使用[a-z][a-z]将该行重定向到文件名。

例如,假设输入:

示例输入文件

print

示例用法

您可以在下面使用对$ cat file 111 222 Time = 0.1 333 444 555 aa bb cc dd 666 Time = 0.2 333 444 555 aa 的简短呼叫:

awk

示例输出文件

awk ' $1 == "Time" { fname=$3 ".txt"; next } /[a-z][a-z]/ { print $0 > fname } ' file (命名为Time = 0.1)的文件为:

"0.1.txt"

$ cat 0.1.txt aa bb cc dd 的文件(名称:Time = 0.2):

"0.2.txt"

仔细研究一下,让我知道我是否理解您的问题,以及您对$ cat 0.2.txt aa 表达式还有其他疑问。


进行第二次修改

在澄清了您不希望像最初显示的awk而是想要在每个[a-z][a-z]行之后的 floating-point 数字之后,所需的更改很小。不用输出匹配Time = ...的行,只需使用正则表达式[a-z][a-z]输出包含'.'的行。

输入文件

[.]

$ cat file2 111 222 Time = 0.1 333 444 555 937463.41 82162.462 762542.16 452621.45 666 Time = 0.2 333 444 555 10383.32 163873.22 9821.001 83638.1209 666 使用情况*

awk

输出文件

$ awk '$1 == "Time" {fname=$3 ".txt"; next} /[.]/{print $0 > fname}' file2

编辑三行-在“时间”之后提取第4-7行

好吧,由于您现在已指定要提取每条$ cat 0.1.txt 937463.41 82162.462 762542.16 452621.45 $ cat 0.2.txt 10383.32 163873.22 9821.001 83638.1209 行之后的第4-7行,因此您可以执行基本相同的操作,而无需查找例如字符(或浮点数),您只需保留"Time = ..."行之后的行数计数器,并在"Time = ..."时将值输出到每个文件。例如:

count > 3 && count < 8

最初将计数器设置为不匹配任何内容。然后,在遇到awk -v count=8 ' $1 == "Time" {fname=$3 ".txt"; count=1; next} count > 3 && count < 8 {print $0 > fname} {count++} ' file2 时,它将创建文件名并设置"Time = ..."count=1组将为每个读取的记录增加{count++},并且count组在遇到第4-7行时会提取它们。

示例输入文件

count > 3 && count < 8 {print $0 > fname}

然后使用:

$ cat file2
19287.4342
23213.444443
Time = 0.1
333245.4324
0.2432421
98374532.3241
937463.41
82162.462
762542.16
452621.45
12.019288
Time = 0.2
93891.182
103837.3333
937382.32321
10383.32
163873.22
9821.001
83638.1209
443.232111

将产生所需的输出文件:

示例输出文件

$ awk -v count=8 '
    $1 == "Time" {fname=$3 ".txt"; count=1; next}
    count > 3 && count < 8 {print $0 > fname}
    {count++}
' file2

希望我们现在已经解决了解决$ cat 0.1.txt 937463.41 82162.462 762542.16 452621.45 $ cat 0.2.txt 10383.32 163873.22 9821.001 83638.1209 所需的实际问题