2011-10-23 134 views
0

我有一个这样的格式的文件: 两列数字在开始和两列数字在最后和一列在中间这是名字,但是这个名字有一个空间分隔符,它把事情弄糟了。awk/sed正则表达式,提取具有分隔符的列

是否有任何正则表达式可以正确取出名称列。无论如何,我可以使用sed来替换(或删除)该列中的空间,以便我可以轻松地将其列出来?

例子:

1 2 name 3 4 
12 12 name1 name2 3 4 
12 12 name1 name2 name3 name4 3 4 
3 4 name 3 4 

- ,我想有输出是:

name 
name1_name2 
name1_name2_name3_name4 
name 

感谢,

阿米尔,

回答

2

一种解决方案使用AWK是:

cat foo | awk '{ for(i=3; i<=NF-3; i++) { printf $i "_"; } printf $i "\n"; }' 

下面是使用sed的同一件事:

cat foo | sed -e 's/^[0-9 ]*//g' -e 's/ [0-9 ]*$//g' -e 's/ /_/g' 

POSIX兼容的清晰度:

cat foo | sed -e 's/^[[:digit:][:space:]]*//g' -e 's/[[:space:]]*[[:digit:][:space:]]*$//g' -e 's/ /_/g' 
+0

1)你为什么在这里使用的管道? Sed和awk可以从参数获取输入文件。 –

+0

2)为什么要为所有这些小脚本添加新的'-e'。所有这些都可以更加紧凑和易于理解。 –

+0

@dmalikov 1)我不确定他的输出是否是静态文件。 2)它是一个流编辑器,解决方案是多个编辑,编辑的顺序很重要...... –

1
sed 's/^[0-9]\+ [0-9]\+ \(.*\) [0-9]\+ [0-9]\+$/\1/;s/ /_/g' 
1

另一个awk的方式不用循环

awk 'BEGIN{OFS="_"}{$1=$2=$NF=$(NF-1)="";gsub(/__/,"")}1' yourFile 

测试

kent$ cat t 
1 2 name 3 4 
12 12 name1 name2 3 4 
12 12 name1 name2 name3 name4 3 4 
3 4 name 3 4 

kent$ awk 'BEGIN{OFS="_"}{$1=$2=$NF=$(NF-1)="";gsub(/__/,"")}1' t 
name 
name1_name2 
name1_name2_name3_name4 
name 
0

夫妇的Perl的选项

perl -lne '/\d+ \d+ (.+) \d+ \d+/ and do {($_ = $1) =~ s/ /_/g; print}' 
perl -lape 'for (1..2) {shift @F; pop @F}; $_ = join "_", @F'