Включить переменные в строку кода bash - PullRequest
0 голосов
/ 20 декабря 2011

Ну, может быть, это не лучший заголовок; но трудно передать мое намерение только в коротком заголовке.

У меня есть строка здесь:

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

Итак, основная проблема - извлечь это 118610566 из 8-го столбца.

Я знаю, как получить этот номер:

$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}'`

ТНХ

Ответы [ 3 ]

3 голосов
/ 20 декабря 2011

Может быть, это может помочь -

[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 голос
/ 20 декабря 2011

С небольшими манипуляциями со строками вы можете получить его за один раз.

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, как и в большинстве движков регулярных выражений, * равен жадным , что означает, что он берет самое длинное совпадение, которое он может получить, поэтому мы знаем, что оно получит первое ;.

И все, что нам осталось, это номер, который вы хотите.

0 голосов
/ 20 декабря 2011

Если ваши «столбцы» всегда разделены пробелами, вам не нужно использовать подоболочки и awk, вы можете сделать это прямо в оболочке:

[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

соль по вкусу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...