将基于行的条目转换为基于shell的列

时间:2012-02-17 02:04:16

标签: parsing shell data-conversion reformat

我需要您在不同列的多行条目中提供帮助。并对文件中的所有条目执行相同操作。

文件示例(仅显示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}'

但是如何通过阅读整个文件来完成所有条目?

3 个答案:

答案 0 :(得分:1)

您可以像这样使用awk

awk 'NR%2 { printf "%s%s", $0, (NR+1)%6 ? " " : "\n" }' < test


说明:

您需要了解awk

这两件事
  • 语法为condition { commands },如果commands为真(非零),则执行condition

  • 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;等等。

答案 1 :(得分:0)

这是使用Perl的一种方式:

perl -ne 'chomp; if($. % 2 == 1) { print $_, ($. % 6 == 5) ? "\n" : "\t" }'

这将打印文件的第1行,第3行,第5行,第7行等。在第5,11,17等行之后,它会打印一个换行符;在其他行之后,它将只打印一个标签。

(注意:这假设在五行的连续组之间只有一个空行。如果的话,那么请澄清。)

答案 2 :(得分:0)

我认为您使用原始的awk解决方案走在了正确的轨道上。试试这个;我认为这是可读性和有效性的良好结合:

awk 'BEGIN { RS="\n\n" } ; { print $1, $3, $5 }' < myfile

这个想法是告诉awk将空行(2个连续的换行符)视为记录分隔符。然后将每个节视为单个记录,并将空格(在本例中为单个换行符)分隔字段。这非常类似于您使用tr所做的,除非现在awk将遍历处理一节的整个文件。