使用UNIX或perl从每行文本文件中提取某些文本

时间:2013-03-07 20:56:57

标签: linux unix text-processing

我有一个包含这样的行的文本文件:

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的某些组合可能?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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     

答案 2 :(得分:1)

我的解决方案使用sed

sed 's/\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]\)*/\1     \2      \3/g' file.txt