0

我需要你的帮助,将多行输入到不同的列中。并对文件中的所有条目执行相同的操作。

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

但是如何通过读取整个文件来处理所有条目?

4

3 回答 3

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

于 2012-02-17T02:49:39.420 回答
0

这是使用 Perl 的一种方法:

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

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

(注意:这假设在连续的五行组之间恰好有一个空行。如果不是这种情况,请澄清。)

于 2012-02-17T02:15:38.513 回答
0

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

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

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

于 2012-02-17T05:18:06.457 回答