首页 > 解决方案 > 基于模式匹配行并重新格式化文件 Bash/ Linux

问题描述

我正在寻找解决以下问题的 bash/Linux 方法。

我有一个input.txt看起来像这样的文本文件()(还有更多行):

TCCTCCGC+TAGTTAGG_Vel_24_CC_LlanR_34    CC_LlanR
GGAGTATG+TCTATTCG_Vel_24_CC_LlanR_22    CC_LlanR
TTGACTAG+TGGAGTAC_Vel_02_EN_DavaW_11    EN_DavaW
TCGAATAA+TGGTAATT_Vel_24_CC_LlanR_23    CC_LlanR
CTGCTGAA+CGTTGCGG_Vel_02_EN_DavaW_06    EN_DavaW
index_07_barcode_04_PA-17-ACW-04        17-ACW
index_09_barcode_05_PA-17-ACW-05        17-ACW
index_08_barcode_37_PA-21-YC-15         21-YC
index_09_barcode_04_PA-22-GB-10         22-GB
index_10_barcode_37_PA-28-CC-17         28-CC
index_11_barcode_29_PA-32-MW-07         32-MW
index_11_barcode_20_PA-32-MW-08         32-MW

我想生成一个看起来像的文件

CC_LlanR(TCCTCCGC+TAGTTAGG_Vel_24_CC_LlanR_34,GGAGTATG+TCTATTCG_Vel_24_CC_LlanR_22,TCGAATAA+TGGTAATT_Vel_24_CC_LlanR_23)
EN_DavaW(TTGACTAG+TGGAGTAC_Vel_02_EN_DavaW_11,CTGCTGAA+CGTTGCGG_Vel_02_EN_DavaW_06)
17-ACW(index_07_barcode_04_PA-17-ACW-04,index_09_barcode_05_PA-17-ACW-05)
21-YC(index_08_barcode_37_PA-21-YC-15)
22-GB(index_09_barcode_04_PA-22-GB-10)
28-CC(index_10_barcode_37_PA-28-CC-17)
32-MW(index_11_barcode_29_PA-32-MW-07,index_11_barcode_20_PA-32-MW-08)

我想我可以按照这个思路做点什么。

cat input.txt | awk '{print $1}' | grep -e "CC_LlanR" | paste -sd',' > intermediate_file
cat input.txt | awk '{print $2"("}' something something??

但我只知道如何一次 grep 一种模式?有没有办法一次找到所有匹配的行并以这种格式输出?

谢谢!(祝大家复活节快乐/长周末!)

标签: linuxbashawksedgrep

解决方案


使用您显示的示例,请尝试以下操作。

awk '
FNR==NR{
  arr[$2]=(arr[$2]?arr[$2]",":"")$1
  next
}
($2 in arr){
  print $2"("arr[$2]")"
  delete arr[$2]
}
' Input_file Input_file

第二种解决方案:在 Input_file 的单次读取中尝试以下操作。

awk '{arr[$2]=(arr[$2]?arr[$2]",":"")$1} END{for(i in arr){print i"("arr[i]")"}}' Input_file

说明(第一种解决方案):在此处添加第一种解决方案的详细说明。

awk '                      ##Starting awk program from here.
FNR==NR{                   ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
  arr[$2]=(arr[$2]?arr[$2]",":"")$1 ##Creating array with index of 2nd field and keep adding its value with comma here.
  next                     ##next will skip all further statements from here.
}
($2 in arr){               ##Checking condition if 2nd field is present in arr then do following.
  print $2"("arr[$2]")"    ##Printing 2nd field ( arr[$2] ) here.
  delete arr[$2]           ##Deleteing arr value with 2nd field index here.
}
' Input_file Input_file    ##Mentioning Input_file names here.

推荐阅读