0

我有一个包含内容的文本文件 test.hd

gated window upper limit:=1.15
gated window lower limit:=0.87
gated frame mode:=variable time
gated beats accepted:=631
gated beats rejected:=1
gated longest beat:=1.0455
gated shortest beat:=0.8722
gated average beat:=0.9472
applied zoom:=2.15
zoom origin x:=272
zoom origin y:=288

在我的 shell 脚本中,我想使用 sed 或 perl one liner 分配一个变量最长节拍和最短节拍。目前我可以用更多,grep 和 cut

more test.hd | grep 'longest beat' | cut -f 2 -d =
4

6 回答 6

2

这是一种使用方法sed

longest_beat=$(sed -n '/longest beat/s/.*=//p' test.hd)
shortest_beat=$(sed -n '/shortest beat/s/.*=//p' test.hd)
于 2013-02-18T12:43:25.990 回答
2

您可以使用简单的正则表达式来捕获目标值:

use strict;
use warnings;

my ($short, $long);
while (<DATA>) {
    if (/longest beat:=(\S+)/) {
        $long = $1;
    } elsif (/shortest beat:=(\S+)/) {
        $short = $1;
    }
}
print "Longest beat: $long\n";
print "Shortest beat: $short\n";

__DATA__
gated window upper limit:=1.15
gated window lower limit:=0.87
gated frame mode:=variable time
gated beats accepted:=631
gated beats rejected:=1
gated longest beat:=1.0455
gated shortest beat:=0.8722
gated average beat:=0.9472
applied zoom:=2.15
zoom origin x:=272
zoom origin y:=288

输出:

Longest beat: 1.0455
Shortest beat: 0.8722

文件句柄可以是你需要的DATA任何文件句柄,当然这只是为了演示。

更通用的版本是简单地提取所有键/值对:

my %data;
while (<DATA>) {
    chomp;
    my ($key, $value) = split /:=/, $_, 2;   # split on := max two fields
    $data{$key} = $value;
}
print "Longest beat: $data{'gated longest beat'}\n";
print "Shortest beat: $data{'gated shortest beat'}\n";
于 2013-02-18T12:31:38.997 回答
1
long=`perl -F"=" -ane 'print $F[1] if(/longest beat/)' your_file`
short=`perl -F"=" -ane 'print $F[1] if(/shortest beat/)' your_file`

also you can use:

sed -n 's/.*longest beat:=//gp'

tested below:

> cat temp
gated window upper limit:=1.15
gated window lower limit:=0.87
gated frame mode:=variable time
gated beats accepted:=631
gated beats rejected:=1
gated longest beat:=1.0455
gated shortest beat:=0.8722
gated average beat:=0.9472
applied zoom:=2.15
zoom origin x:=272
zoom origin y:=288
> 
> 
> 
> cat temp.sh
#!/bin/sh


long=`perl -F"=" -ane 'print $F[1] if(/longest beat/)' temp`
short=`perl -F"=" -ane 'print $F[1] if(/shortest beat/)' temp`

echo $long
echo $short
> 
> 
> ./temp.sh
1.0455
0.8722
>
> cat temp.sh
#!/bin/sh


long=`sed -n 's/.*longest beat:=//gp' temp`
short=`perl -F"=" -ane 'print $F[1] if(/shortest beat/)' temp`

echo $long
echo $short
> ./temp.sh
1.0455
0.8722
> 
于 2013-02-18T12:38:03.170 回答
1

这是使用带有哈希的捕获的一个选项:

use strict;
use warnings;

my %hash;

while (<DATA>) {
    $hash{$1} = $2 if /((?:longest|shortest) beat):=(\S+)/;
}

print "\u$_: $hash{$_}\n" for keys %hash;

__DATA__
gated window upper limit:=1.15
gated window lower limit:=0.87
gated frame mode:=variable time
gated beats accepted:=631
gated beats rejected:=1
gated longest beat:=1.0455
gated shortest beat:=0.8722
gated average beat:=0.9472
applied zoom:=2.15
zoom origin x:=272
zoom origin y:=288

输出:

Shortest beat: 0.8722
Longest beat: 1.0455
于 2013-02-18T19:44:31.240 回答
1

more这里不需要。您可以指定文件名grep或将其重定向到其标准输入。然后,使用命令替换:

longest_beat=$(grep 'longest beat' test.hd | cut -d= -f2)
于 2013-02-18T12:28:25.520 回答
1

像这样的东西怎么样:

my ($longest_beat, $shortest_beat);

while (<DATA>) { # insert your own filehandle here
  $longest_beat  = $1, next if /longest beat:=\s*(\S+)/; 
  $shortest_beat = $1, next if /shortest beat:=\s*(\S+)/;
}

print $longest_beat, "\n";
print $shortest_beat, "\n";    

演示

于 2013-02-18T12:30:27.533 回答