那么也许这不是最好的标题;但很难用简短的标题表达我的意图。
我在这里有一句话:
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列开始这个118610566
。
我知道如何grep这个数字:
$c=`cat line|awk '{print $8}'|sed 's/;/\t/g'|awk '{print $1}'|sed 's/\END=//g'`
但我的问题是如何将此变量合并到另一个bash行中:
what_i_want=`cat line|awk '{print $1"\t"$2"\t"$c}'`
THX
答案 0 :(得分: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
FS
是awk's
内置变量。它默认为空格或制表符。由于您的行作为多个分隔符设置FS
到一个字符类有助于拆分每个去限制器的行。我们在此定义的字符类是space
,semi-colon
或equal
。
可能会觉得有点奇怪,但我用这个作为我的调试工具来识别列,当我碰巧用一个以上的分隔符解析一行时。这就是我从你的行中得到的 -
[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
您还可以通过以下方式使用substr
的简单awk
内置函数 -
[jaypal:~/Temp] awk '{print $1,$2,$8=substr($8,5,9)}' tmp
2 118610455 118610566
答案 1 :(得分:1)
通过一些字符串操作,您可以一次性完成。
what_i_want=$(awk '{sub(/^END=/,"",$8); sub(/;.*$/,"",$8); print $1,$2,$8}' line)
一些解释:
sub(a,b,c)
在变量a
中搜索模式c
并将其替换为b
,将修改后的字符串存储回c
。模式写在//
。
^
是字符串的开头,$
是结尾,.
是任意内容,*
表示前面的模式中的零个或多个。所以在我们的案例中:
sub(/^END=/,"",$8);
在字符串的开头(END=
)匹配^
并将其替换为""
,没有,基本上将其删除。
sub(/;.*$/,"",$8);
将.*
中的所有内容(;
)带到最后($
)并删除它。请注意,在awk中,与大多数正则表达式引擎一样,*
是 greedy ,这意味着它需要获得最长的匹配,因此我们知道这将获得第一个;
。
我们剩下的就是你想要的数字。
答案 2 :(得分:0)
如果您的“列”始终用空格分隔,那么您不需要使用子shell和awk,您可以直接在shell中执行此操作:
[ghoti@pc ~]$ 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"
[ghoti@pc ~]$ echo "$five"
<DUP:TANDEM>
[ghoti@pc ~]$ echo "$junk"
40 . END=118610566;SVLEN=110;SVTYPE=TDUP;CIPOS=-100,55;CIEND=-56,100;IMPRECISE;DBVARID=esv7540;VALIDATED;VALMETHOD=CGH;SVMETHOD=RP
read
行中指定的最后一个变量获取“其他所有内容”。
另外。如果你正在处理这样的多行,你可以循环运行它:
cat /path/to/inputfile | while read one two three four five junk; do
echo "$one - $two - $five"
done
盐味。