2011-12-19 52 views
0

也许这不是最好的标题;但很难用简短的标题来表达我的意图。将变量合并到bash代码行中

我在这里的行:

2 118610455 P2_PM_2_5034 T <DUP:TANDEM> 40 . END=118610566;SVLEN=110;SVTYPE=TDUP;CIPOS=-100,55;CIEND=-56,100;IMPRECISE;DBVARID=esv7540;VALIDATED;VALMETHOD=CGH;SVMETHOD=RP 

基本上我想它转换成:

2 118610455 118610566 

所以主要问题是从第8列的grep这个118610566

我知道如何用grep这个数字:

$c=`cat line|awk '{print $8}'|sed 's/;/\t/g'|awk '{print $1}'|sed 's/\END=//g'` 

,但我的问题是,那么我怎么可以将这个变量到另一个庆典线:

what_i_want=`cat line|awk '{print $1"\t"$2"\t"$c}'` 

THX

回答

1

一个小字符串操作,你可以一口气拿到它。

what_i_want=$(awk '{sub(/^END=/,"",$8); sub(/;.*$/,"",$8); print $1,$2,$8}' line) 

一些说明:在可变c

sub(a,b,c)搜索图案a并用b替换它,存储修改后的字符串返回到c。模式写在//之内。

^是字符串的开头,$是结束时,.是什么,和*表示零或多个前述图案。因此,在我们的例子:

sub(/^END=/,"",$8);比赛END=在字符串的开头(^),并与"",没有什么替代它,基本上是将其删除。

sub(/;.*$/,"",$8);将从;到($)的所有内容(.*)都取出并删除它。请注意,在awk中,与大多数正则表达式引擎一样,*贪婪,这意味着它需要最长的匹配,所以我们知道这将得到第一个;

而我们剩下的就是你想要的数字。

+0

thx很好......但你能否解释一下sub(/;.*/,"",$$ 8)?我知道在这里截断了部分;对?但我不明白是什么。 *表示这里。 – user815408 2011-12-19 22:07:47

+0

添加了解释。 – Kevin 2011-12-19 22:21:22

3

可能这可以帮助 -

[jaypal:~/Temp] cat tmp 
2 118610455 P2_PM_2_5034 T <DUP:TANDEM> 40 . END=118610566;SVLEN=110;SVTYPE=TDUP;CIPOS=-100,55;CIEND=-56,100;IMPRECISE;DBVARID=esv7540;VALIDATED;VALMETHOD=CGH;SVMETHOD=RP 

[jaypal:~/Temp] var=$(awk -v FS="[ ;=]" '{print $1,$4,$24}' tmp) 

[jaypal:~/Temp] echo $var 
2 118610455 118610566 

FSawk's内置变量。它默认为空格或制表符。由于您的行作为多个分隔符,因此将FS设置为字符类有助于为每个解除限制器分割行。我们在这里定义的字符类是space,semi-colonequal

可能会觉得有点奇怪,但是当我碰巧用一个以上的分隔符分析一行时,我将它用作识别列的调试工具。这是我从你的线了 -

[jaypal:~/Temp] awk -v FS="[ ;=]" '{for(i=1;i<=NF;i++) print "$"i" is "$i}' tmp 
$1 is 2 
$2 is 
$3 is 
$4 is 118610455 
$5 is 
$6 is 
$7 is P2_PM_2_5034 
$8 is 
$9 is 
$10 is 
$11 is T 
$12 is 
$13 is 
$14 is <DUP:TANDEM> 
$15 is 
$16 is 
$17 is 
$18 is 40 
$19 is 
$20 is . 
$21 is 
$22 is 
$23 is END 
$24 is 118610566 
$25 is SVLEN 
$26 is 110 
$27 is SVTYPE 
$28 is TDUP 
$29 is CIPOS 
$30 is -100,55 
$31 is CIEND 
$32 is -56,100 
$33 is IMPRECISE 
$34 is DBVARID 
$35 is esv7540 
$36 is VALIDATED 
$37 is VALMETHOD 
$38 is CGH 
$39 is SVMETHOD 
$40 is RP 

您也可以通过以下方式使用awk简单substr内置功能 -

[jaypal:~/Temp] awk '{print $1,$2,$8=substr($8,5,9)}' tmp 
2 118610455 118610566 
+0

thx但你能解释一下FS =“[; =]”有点吗?我不知道为什么11861045成为第4列。 – user815408 2011-12-19 22:00:41

0

如果你的“列”总是分开由空格,那么你就需要使用子shell和awk,可以在外壳直接做到这一点:

[[email protected] ~]$ read one two three four five junk <<< "2 118610455 P2_PM_2_5034 T <DUP:TANDEM> 40 . END=118610566;SVLEN=110;SVTYPE=TDUP;CIPOS=-100,55;CIEND=-56,100;IMPRECISE;DBVARID=esv7540;VALIDATED;VALMETHOD=CGH;SVMETHOD=RP" 
[[email protected] ~]$ echo "$five" 
<DUP:TANDEM> 
[[email protected] ~]$ echo "$junk" 
40 . END=118610566;SVLEN=110;SVTYPE=TDUP;CIPOS=-100,55;CIEND=-56,100;IMPRECISE;DBVARID=esv7540;VALIDATED;VALMETHOD=CGH;SVMETHOD=RP 

您指定的最后一个变量3210线获得“其他”。

另外。如果你正在处理这样的多行,你可以在一个循环中运行它:

cat /path/to/inputfile | while read one two three four five junk; do 
    echo "$one - $two - $five" 
done 

盐的味道。