【问题标题】:How to parse a file in bash according to another file [duplicate]如何根据另一个文件解析bash中的文件[重复]
【发布时间】:2017-01-15 04:39:52
【问题描述】:

我有一个非常危险的问题,我将在下面的示例中展示我的解决方案。我宁愿在 awk 中解决这个问题。但是任何功能性解决方案都将受到欢迎。

我有 template 文件,它告诉我列的顺序(按此顺序):

模板:

IMPACT;DISTANCE;STRAND;FLAGS;VARIANT_CLASS;SYMBOL;SYMBOL_SOURCE;HGNC_ID;BIOTYPE;CANONICAL;TSL;APPRIS;CCDS;ENSP;SWISSPROT;TREMBL;UNIPARC;REFSEQ_MATCH;GENE_PHENO;SIFT;PolyPhen;EXON;INTRON;DOMAINS;HGVSc;HGVSp;HGVS_OFFSET;GMAF;AFR_MAF;AMR_MAF;EAS_MAF;EUR_MAF;SAS_MAF;AA_MAF;EA_MAF;ExAC_MAF;ExAC_Adj_MAF;ExAC_AFR_MAF;ExAC_AMR_MAF;ExAC_EAS_MAF;ExAC_FIN_MAF;ExAC_NFE_MAF;ExAC_OTH_MAF;ExAC_SAS_MAF;CLIN_SIG;SOMATIC;PHENO;PUBMED;MOTIF_NAME;MOTIF_POS;HIGH_INF_POS;MOTIF_SCORE_CHANGE

所有值都用分号分隔。

这是我的输入文件,我无法解析,因为 template 中的某些值丢失了。

输入:

IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=deletion;SYMBOL=KIF1B;BIOTYPE=protein_coding;ENSP=NP_055889.2;INTRON=24/46;HGVSc=NM_015074.3:c.2537+467delT;HGVS_OFFSET=9
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=deletion;SYMBOL=KIF1B;BIOTYPE=protein_coding;CANONICAL=YES;ENSP=XP_005263490.1;INTRON=26/48;HGVSc=XM_005263433.1:c.2675+467delT;HGVS_OFFSET=9
IMPACT=MODIFIER;DISTANCE=4811;STRAND=-1;VARIANT_CLASS=deletion;SYMBOL=C1orf127;BIOTYPE=protein_coding;CANONICAL=YES;ENSP=NP_001164225.1;GMAF=-:0.1749;AMR_MAF=-:0.3011;EAS_MAF=-:0.1542;EUR_MAF=-:0.0794;SAS_MAF=-:0.2008;AA_MAF=-:0.091
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;BIOTYPE=misc_RNA;CANONICAL=YES;INTRON=1/1;HGVSc=XR_158744.2:n.96+764dupA;HGVS_OFFSET=8;GMAF=A:0.4225;AMR_MAF=A:0.2723;EAS_MAF=A:0.5187;EUR_MAF=A:0.4643;SAS_MAF=A:0.3767;AA_MAF=A:0.5613
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;BIOTYPE=misc_RNA;INTRON=1/1;HGVSc=XR_241119.1:n.41+204dupA;HGVS_OFFSET=8;GMAF=A:0.4225;AMR_MAF=A:0.2723;EAS_MAF=A:0.5187;EUR_MAF=A:0.4643;SAS_MAF=A:0.3767;AA_MAF=A:0.5613
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;SYMBOL=SDHC;BIOTYPE=protein_coding;ENSP=NP_001030588.1;INTRON=2/4;HGVSc=NM_001035511.1:c.77+43dupT;HGVS_OFFSET=11
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;SYMBOL=SDHC;BIOTYPE=protein_coding;ENSP=NP_001030589.1;INTRON=2/4;HGVSc=NM_001035512.1:c.77+43dupT;HGVS_OFFSET=11
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;SYMBOL=SDHC;BIOTYPE=protein_coding;ENSP=NP_001030590.1;INTRON=1/3;HGVSc=NM_001035513.1:c.20+9288dupT;HGVS_OFFSET=11
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;SYMBOL=SDHC;BIOTYPE=protein_coding;ENSP=NP_001265101.1;INTRON=2/3;HGVSc=NM_001278172.1:c.77+43dupT;HGVS_OFFSET=11
IMPACT=MODIFIER;STRAND=1;VARIANT_CLASS=insertion;SYMBOL=SDHC;BIOTYPE=protein_coding;CANONICAL=YES;ENSP=NP_002992.1;INTRON=2/5;HGVSc=NM_003001.3:c.77+43dupT;HGVS_OFFSET=1

我想要制表符分隔的输出。如果模板中缺少任何 INPUT 值,请在此处放置- 标记。基本上我需要在同一列中使用相同的值。

输出示例:

IMPACT  DISTANCE    STRAND  FLAGS   VARIANT_CLASS   SYMBOL  SYMBOL_SOURCE   HGNC_ID BIOTYPE
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=KIF1B    -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=KIF1B    -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER DISTANCE=4811   STRAND=-1   -   VARIANT_CLASS=deletion  -   SYMBOL=C1orf127 -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion -   -   -   BIOTYPE=misc_RNA
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion     -   -   BIOTYPE=misc_RNA
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=insertion SYMBOL=SDHC -   -   BIOTYPE=misc_RNA
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=misc_RNA
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_coding
IMPACT=MODIFIER -   STRAND=1    -   VARIANT_CLASS=deletion  SYMBOL=SDHC -   -   BIOTYPE=protein_codin

注意:在示例输出中,我没有所有列。

我的尝试只是用 awk 解析 INPUT 文件:

awk -v OFS="\t" '{split($1,arr1,";"); print arr1[1],arr1[2]..}'

此解析效果很好,但不给我命令,也不适用于缺失值。感谢您的帮助。

注意:

这是How to find and print specific character in bash的更多解释问题

【问题讨论】:

  • @JamesBrown,哦,哇——这是一个正确的副本。很好的收获。
  • 好吧,我刚刚为它写了一个 awk 解决方案... :D
  • 这是一个更加解释的版本,添加了模板和标题。我不确定是要编辑还是创建新的。

标签: bash parsing awk


【解决方案1】:

在本机 bash 中轻松完成 - 不需要 awk

#!/usr/bin/env bash
#          ^^^ ^^^^
# uses the bash from your PATH, so on MacOS X, this can use a MacPorts bash 4
# ...vs the 3.x version installed by Apple in /bin.

# read template values into an array
IFS=';' read -r -a template < template

# print header
printf '%s\t' "${template[@]}"; printf '\n'

# declare an associative array (requires bash 4)
declare -A data

# iterate over lines of the input file, reading each into an array
while IFS=';' read -r -a items; do

  # populate the data map with key/value items from this line
  data=( )
  for item in "${items[@]}"; do
    key=${item%%=*}
    value=${item#*=}
    data[$key]=$value
  done

  # iterate over template items, emitting a field for each
  for item in "${template[@]}"; do
    if [[ ${data[$item]} ]]; then
      printf -- '%s=%s\t' "$item" "${data[$item]}"
    else
      printf -- '-\t'
    fi
  done

  # ...and emit a newline after processing each input line
  printf '%s\n'

done <input

【讨论】:

  • 非常感谢查尔斯。它看起来非常好。我刚刚将 printf '-\t' 修复为 printf '\t'。 bash 中的完美解决方案。
  • 如果我使用 printf '-\t' 它会给我一个错误: printf: -\: invalid option.
  • 哦,对不起。应该是printf -- '-\t'
  • done &lt; &lt;(awk ...)
  • 或者,换一种方式,done &lt;&lt;&lt;"$input2"
猜你喜欢
  • 2016-07-23
  • 2023-03-10
  • 1970-01-01
  • 2018-10-10
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多