![使用 Unix 命令解析复杂的文本文件](https://linux22.com/image/55515/%E4%BD%BF%E7%94%A8%20Unix%20%E5%91%BD%E4%BB%A4%E8%A7%A3%E6%9E%90%E5%A4%8D%E6%9D%82%E7%9A%84%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6.png)
我想解析以下文本结构:
>Cluster 423
0 56aa, >HWI-ST1448:257:C3V2HACXX:1:1106:19087:2550.1... at 92.86%
1 64aa, >HWI-ST1448:257:C3V2HACXX:1:1106:15943:81371.1... *
2 41aa, >HWI-ST1448:257:C3V2HACXX:1:1106:12438:91360.3... at 90.24%
3 45aa, >HWI-ST1448:257:C3V2HACXX:1:1108:13046:13861.1... at 91.11%
4 52aa, >HWI-ST1448:257:C3V2HACXX:1:1110:12260:2424.2... at 90.38%
>Cluster 434
0 64aa, >HWI-ST1448:257:C3V2HACXX:1:1106:15723:89894.1... *
1 46aa, >HWI-ST1448:257:C3V2HACXX:2:1312:1967:40935.2... at 97.83%
基本上,标识符*
在末尾标有a,组大小是最后一个组号+1。
我想要产生的输出是(请注意最后的组大小):
HWI-ST1448:257:C3V2HACXX:1:1106:15943:81371.1 5
HWI-ST1448:257:C3V2HACXX:1:1106:15723:89894.1 2
有任何想法吗?
答案1
这是一个有点粗略的(没有错误处理):
awk '/\*$/ { save_id = substr($3, 2, length($3)-4) }
/^[0-9]/ { save_num = $1 }
NR > 1 && /^>/ {print save_id, save_num+1 }
END {print save_id, save_num+1 }
' data_file
*
在以 结尾(即匹配)的行上/*$/
,从第三个单词中提取组 ID,丢弃第一个字符 (>
) 和最后三个字符 (...
)。- 在以数字开头的行中,保存该数字(即第一个单词)。
- 当遇到以 开头
>
(但通过指定 排除文件中的第一行NR > 1
)或文件末尾的行时,输出适当的保存值。
答案2
perl -F'\n' -lan00e 'print "$1\t$#F" if />(.*)\.{3} \*$/m'
答案3
sed '/^[>0-9]/h;s/.*>\(.*[0-9]\).*\*/[\1 ]P /p
$s/.*//;/^[>0-9[]/d;g;s/ .*/ 1+pc/
' <<\DATA | dc
>Cluster 423
0 56aa, >HWI-ST1448:257:C3V2HACXX:1:1106:19087:2550.1... at 92.86%
1 64aa, >HWI-ST1448:257:C3V2HACXX:1:1106:15943:81371.1... *
2 41aa, >HWI-ST1448:257:C3V2HACXX:1:1106:12438:91360.3... at 90.24%
3 45aa, >HWI-ST1448:257:C3V2HACXX:1:1108:13046:13861.1... at 91.11%
4 52aa, >HWI-ST1448:257:C3V2HACXX:1:1110:12260:2424.2... at 90.38%
>Cluster 434
0 64aa, >HWI-ST1448:257:C3V2HACXX:1:1106:15723:89894.1... *
1 46aa, >HWI-ST1448:257:C3V2HACXX:2:1312:1967:40935.2... at 97.83%
DATA
输出
HWI-ST1448:257:C3V2HACXX:1:1106:15943:81371.1 5
HWI-ST1448:257:C3V2HACXX:1:1106:15723:89894.1 2
这很简单。它为任何带有字符的行保留行上第一个数字的副本。仅当它可以成功删除*
作为行中最后一个字符的 或该行不以 开头时,它才会打印>0-9
。最后一行的所有字符都被删除。因此,当在空行上提取保存的数字时,每个字符串dc
都会得到一个[ stuff here ]
字符串和一个小的加法作业。p
Cluster
sed
答案4
grep "\*" file.txt |grep -E "(?<=>)[\w+\s\W]+"|sed 's/\.\.\.\*//'