0

我有一个带有如下行的文本文件:

Sequences (1:4) Aligned. Score:  4
Sequences (100:3011) Aligned. Score: 77
Sequences (12:345) Aligned. Score: 100
...

我希望能够将值提取到一个新的制表符分隔的文本文件中:

1 4 4
100 3011 77
12 345 100

(像这样,但使用制表符而不是空格)

任何人都可以提出任何建议吗?也许是 sed 或 cut 的某种组合?

4

3 回答 3

3

您可以使用 Perl:

cat data.txt | perl -pe 's/.*?(\d+):(\d+).*?(\d+)/$1\t$2\t$3/'

或者,保存到文件:

cat data.txt | perl -pe 's/.*?(\d+):(\d+).*?(\d+)/$1\t$2\t$3/' > data2.txt

小解释:

这里的正则表达式是这样的:

s/RULES_HOW_TO_MATCH/HOW_TO_REPLACE/

如何匹配 = .*?(\d+):(\d+).*?(\d+)

如何替换 = $1\t$2\t$3

在我们的例子中,我们使用以下标记来声明我们希望如何匹配字符串:

  • .*? - 尽可能多地匹配任何字符 ('.') ('*'),只要该字符不匹配正则表达式中的下一个标记(在我们的例子中是 \d)。

  • \d+:\d+ - 匹配至少一个数字后跟冒号和另一个数字

  • .*? - 同上

  • \d+ - 匹配至少一位数字

此外,如果正则表达式中的某些标记在括号中,则表示“保存它以便我以后可以引用它”。第一个括号将被称为“$1”,第二个被称为“$2”等。在我们的例子中:

.*?(\d+):(\d+).*?(\d+)
     $1    $2      $3

最后,我们将 $1、$2、$3 打印出来,并用制表符 (\t) 分隔:

$1\t$2\t$3
于 2013-03-07T21:00:03.943 回答
2

你可以使用 sed:

sed 's/[^0-9]*\([0-9]*\)/\1\t/g' infile

这是一个 BSD sed 兼容版本:

sed 's/[^0-9]*\([0-9]*\)/\1'$'\t''/g' infile

上述解决方案在输出中留下一个尾随标签,附加s/\t$//s/'$'\t''$//分别删除它。

如果您知道每行总是有 3 个数字,则可以使用 grep:

<infile grep -o '[0-9]\+' | paste - - -

所有情况下的输出:

1       4       4       
100     3011    77      
12      345     100     
于 2013-03-07T21:02:17.533 回答
1

我的解决方案使用sed

sed 's/\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]\)*/\1     \2      \3/g' file.txt
于 2013-03-07T21:04:03.697 回答