Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于模式匹配行并重新格式化文件Bash/Linux_Linux_Bash_Awk_Sed_Grep - Fatal编程技术网

基于模式匹配行并重新格式化文件Bash/Linux

基于模式匹配行并重新格式化文件Bash/Linux,linux,bash,awk,sed,grep,Linux,Bash,Awk,Sed,Grep,我正在寻找一个bash/Linux方法来解决下面的问题 我有一个文本文件(input.txt),看起来是这样的(还有更多行): 我想生成一个如下所示的文件 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,CTGCT

我正在寻找一个bash/Linux方法来解决下面的问题

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

我想生成一个如下所示的文件

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一个模式?有没有办法一次找到所有匹配的行并以这种格式输出

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

有了展示的样品,请尝试以下内容

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
awk '{arr[$2]=(arr[$2]?arr[$2]",":"")$1} END{for(i in arr){print i"("arr[i]")"}}' Input_file
第二种解决方案:在一次读取输入文件的过程中,请尝试以下操作

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
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.

假设您的输入按示例中所示的
$2
值分组(如果不是,则只需先对输入运行
排序-k2,2
),每次使用一个过程,在内存中仅存储一个令牌,并以与输入相同的
$2
顺序生成输出:

$ cat tst.awk
BEGIN { ORS="" }
$2 != prev {
    printf "%s%s(", ORS, $2
    ORS = ")\n"
    sep = ""
    prev = $2
}
{
    printf "%s%s", sep, $1
    sep = ","
}
END { print "" }
这可能适用于您(GNU-sed):

将每个操纵行附加到保持空间

在转到下一行之前,将类似的键累积到一行中

删除除最后一行之外的每一行

用保留空间的内容替换最后一行

删除第一个字符(由
H
comand引入的换行伪影)并打印结果


注意:最终的解决方案是未排序的,并且按照原始顺序。

啊-非常感谢!两种方法都非常有效@QPaps,您的欢迎,干杯和愉快的学习。再次感谢@RavinderSingh13,也感谢您的解释,非常有用谢谢您的帮助Ed-另一种很好的方式
sed -E 's/^(\S+)\s+(\S+)/\2(\1)/;H
        x;s/(\n\S+)\((\S+)\)(.*)\1\((\S+)\)/\1(\2,\4)\3/;x;$!d;x;s/.//' file