我有一个包含这样的行的文本文件:
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的某些组合可能?
答案 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