我需要您的帮助,将多行条目放入不同的列中。并对文件中的所有条目执行相同操作。
文件示例(仅显示2个条目,有很多类似的条目):
>ABC
*
AGA-AUUCUC-CGGUUCAAUCU
|||
UCUAUAACCGCGCCGAGUUAGU
>ABC
*
AGAUAU-GCUGCAGGCUCAAUUG
||||||
UCUAUAACCGCG-CCGAGUUAGU
要求的文件格式:
>ABC AGA-AUUCUC-CGGUUCAAUCU UCUAUAACCGCGCCGAGUUAGU
>ABC AGAUAU-GCUGCAGGCUCAAUUG UCUAUAACCGCG-CCGAGUUAGU
我能够通过以下方式将单个条目转换为所需格式:
tr 'n' 't' <test3 | awk '{print $1,$3,$5}'
但如何通过读取整个文件来处理所有条目呢?
您可以这样使用awk
:
awk 'NR%2 { printf "%s%s", $0, (NR+1)%6 ? " " : "n" }' < test
解释:
关于awk
,您需要了解以下两件事:
语法为
condition { commands }
,其中如果condition
为真(非零)则执行commands
。NR
是当前记录的编号(即行号),从1开始。
这里,条件是NR%2
,其对于奇数行是非零的。因此,该命令只对奇数行执行,而奇数行正是您要打印的行。偶数行被无声地丢弃。
printf
将打印每一个奇数行,后跟一个空格或一个换行符。您的输入每6行重复一次,并且您希望在第5、11、17、行等行之后有一个换行符。你可以把这些数字加1,使其可以被6整除,所以公式(NR+1)%6
对这些数字来说是0。
因此,(NR+1)%6 ? " " : "n"
计算为第1行和第3行的一个空格,以及第5行的一条换行符。然后重复7、9和11;等等。
我认为您使用最初的awk
解决方案是正确的。试试这个;我认为这是可读性和有效性的良好结合:
awk 'BEGIN { RS="nn" } ; { print $1, $3, $5 }' < myfile
这个想法是告诉awk将空行(2个连续的换行符)视为记录分隔符。然后,每个节都被视为一个单独的记录,空白(在本例中是单个换行符)将字段分隔开。这与您使用tr
所做的非常相似,只是现在awk将一次运行整个文件处理一个节。
这里有一种使用Perl的方法:
perl -ne 'chomp; if($. % 2 == 1) { print $_, ($. % 6 == 5) ? "n" : "t" }'
这将打印文件的第1行、第3行、第5行、第7行等。在第5行、第11行、第17行等之后,它将打印一行换行符;在其他行之后,它将只打印一个选项卡。
(注意:这假设在连续的五行组之间只有一行空白。如果情况不是,请澄清。)