我想用包含数千行
的文本文件执行以下操作B
开头的行(但不包括此行)。<number of lines> " 120"
)>
)我尝试过以下代码,允许我拆分文件,但文件中存在的行数(如NR-1 " 120"
中所示)是累积的,并且打印在拆分文件的最后而不是在开始。
awk '/^B/{n++; print NR-1 " 120" > filename;close(filename);next}{filename = "part" n ".txt"; print >filename}'
在我尝试将其打印为标题时,我使用了以下代码。但是假定的标题根本没有出现。
awk 'BEGIN{print NR-1 " 120" > filename}; /^B/{n++;close(filename);next};{filename = "part" n ".txt"; print >filename}' inputfile.txt
以上代码附带以下错误:
awk: null file name in print or getline
source line number 1
我的文本文件类似于:
>L1212 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L1222 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L1232 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
B * - |1|
>L4212 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4312 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4412 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4512 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
B * - |2|
>L4212 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4312 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4412 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4512 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4312 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4412 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
>L4512 ATCTATCTTCTATCTGTTAGCTAGCTAGCTA
B * - |3|
更新:
在不使用Mawk或GNU awk的情况下使用@ mklement0脚本的回旋处,我在textwrangler中使用grep将所有以B
开头的行更改为单个字符~
。
答案 0 :(得分:1)
使用GNU Awk或Mawk:
awk -v RS='\nB \\* - \\|[0-9]+\\|\n' 'NF {
numLines = gsub("(^|\n)>", "\n") # replace line-initial ">" and count lines in block
fname = "part" ++n # determine next output filename
printf "%s%s\n", numLines " 120", $0 > fname # output header + block
close(fname) # close output file
}' file
注意:除非输入文件中的最后一行是分隔线,否则最后一个输出文件将有一个尾随空行(但是标题中的数据行计数是正确的) - OP有确认这不是问题。
需要GNU Awk或Mawk,因为只有它们支持基于多字符的基于正则表达式的RS
(输入记录分隔符)值 - 与macOS附带的BSD awk
不同。 可能以不同的方式解决这个问题,但这会更麻烦。
brew install gawk
或brew install mawk
。该方法通过B
分隔符行将输入分解为行的块。因此,每个这样的块必须作为一个整体适合存储器(可能是由于执行字符串替换而一次两个副本。
在将写入输出文件之前将整个行存储在中,这样就可以预先计算行数并将该信息添加到标题
numLines = gsub("(^|\n)>", "\n")
执行删除行初始>
字符。并确定块中的行数,利用gsub()
返回替换次数的事实。