Баш, как получить значение после N вхождений разделителя? - PullRequest
1 голос
/ 08 апреля 2019

Мне нужна помощь с bash в Linux; Мне нужно найти команду, которая выполняет следующую операцию.

У меня есть файл, где поля разделены | символ, и я должен выбрать значения, которые появляются после 51 появления этого символа и до появления следующего.

Эта команда bash, если применить ее к следующему файлу, вернет / выберет только значение 0.02468

Пример файла:

AB=0.543;AC=1;AF=0.5;AN=1;BaseQRankSum=-8.244;DB;DP=178;DS;Dels=0;FS=0.568;GC=36;HRun=0;HaplotypeScore=3.5479;MQ=59.09;MQ0=0;MQRankSum=-1.171;QD=12.69;ReadPosRankSum=-0.923;SB=-1203.97;SBD=0.83;VQSLUD=7.2941;culprit=MQRankSum;set=GGSKSNP;CSQ=C|missense_variant|MODERATE|SLC7A2|ENSG00000003487|Transcript|ENST00000001234|protein_coding|7/8||ENST00000001234.10:c.1223G>C|ENSP00000001234.10:p.Cys416Ser|1234|1234|123|C/S|tGt/tCt|rs1234567||1||SNV|HGNC|123456|YES|||CCDS12345.1|ENSP00000004531|P52569||UPI1234A123A4||Ensembl|G|G|||tolerated(0.41)|benign(0)|Pfam_domain:PF12345&hmmpanther:PTHR12345&hmmpanther:PTHR12345:SF242&TIGRFAM_domain:TIGR00906|||0.0613|0|0.0202|0.2421|0|0.0501|0.0006809|0.0003488|0.02468|

Может кто-нибудь помочь мне с этой командой bash? Я пытался найти его в Интернете, но ничего не смог найти.

Ответы [ 4 ]

6 голосов
/ 08 апреля 2019

Используйте cut.Он используется, ну, чтобы «разрезать» строку между разделителями.Пример:

cut -d"|" -f52 <<EOF
AB=0.543;AC=1;AF=0.5;AN=1;BaseQRankSum=-8.244;DB;DP=178;DS;Dels=0;FS=0.568;GC=36;HRun=0;HaplotypeScore=3.5479;MQ=59.09;MQ0=0;MQRankSum=-1.171;QD=12.69;ReadPosRankSum=-0.923;SB=-1203.97;SBD=0.83;VQSLUD=7.2941;culprit=MQRankSum;set=GGSKSNP;CSQ=C|missense_variant|MODERATE|SLC7A2|ENSG00000003487|Transcript|ENST00000001234|protein_coding|7/8||ENST00000001234.10:c.1223G>C|ENSP00000001234.10:p.Cys416Ser|1234|1234|123|C/S|tGt/tCt|rs1234567||1||SNV|HGNC|123456|YES|||CCDS12345.1|ENSP00000004531|P52569||UPI1234A123A4||Ensembl|G|G|||tolerated(0.41)|benign(0)|Pfam_domain:PF12345&hmmpanther:PTHR12345&hmmpanther:PTHR12345:SF242&TIGRFAM_domain:TIGR00906|||0.0613|0|0.0202|0.2421|0|0.0501|0.0006809|0.0003488|0.02468|
EOF

выведет ожидаемый.

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

Мы можем использовать awk:

awk -vFS="|" '{print $52}'

Мы можем прочитать строку в массив и вывести значение 51:

IFS="|" read -r -a arr
echo "${arr[51]}"

Мы можем использовать чтение, чтобы опустить первые 51 значение, например:

IFS="|" read -r _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ val _
echo "$val"
2 голосов
/ 09 апреля 2019

Еще один странный способ с sed:

sed 's/|[^|]*//52g;s/.*|//'
2 голосов
/ 08 апреля 2019

Вы можете использовать sed -E:

sed -E "s:^([^\|]*\|){51}([^\|]*).*$:\2:"

Попробуйте онлайн!

В качестве альтернативы, вы можете использовать чистый BASH:

read temp
for i in {1..51}; do
    temp="${temp#*|}"
done
echo "${temp%%|*}"

Попробуйте онлайн!

awk, IFS и cut подходы приведены выше.

Лично я согласен, что cut должен быть победителем, так как его гораздо проще запомнить, чем любой другой метод, указанный в теме.

1 голос
/ 09 апреля 2019

Следуя советам Эда Мортона.Самый простой и самый элегантный подход - awk:

    awk -F'|' '{print $52}'

Объяснение:

-F'|' заставляет разделитель поля по умолчанию иметь символ |.

'{print $52}' поле печати № 52.

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