2014-06-27 36 views
0

我有以下格式操纵空间分隔的文本文件

4 This is my test file 4500 
5 This is test 6000 
6 Not sure how it will work 9000 

I want to extract data as follows 

Field1 = 4 
Field2 = This is my test file 
Field3 = 4500 

这是第一行的文本文件,我想在这个格式的所有行。任何人都可以帮忙吗?我想做sed或awk no perl。我宁愿sed和/或awk。

我与Field2(可能是单个单词或多个单词字符串)用单引号或双引号括起来的问题。休息我猜很容易。请帮助

+0

我真的无法真正地称这是一个合适的空格分隔文件,因为它不能将空格作为分隔符与空格区分为值。 – MxyL

回答

4

使用sed ...

sed -re 's/(\S+)\s+(.*)\s+(\S+)/Field1 = \1\nField2 = \2\nField3 = \3/g' file 

输出:

Field1 = 4 
Field2 = This is my test file 
Field3 = 4500 
Field1 = 5 
Field2 = This is test 
Field3 = 6000 
Field1 = 6 
Field2 = Not sure how it will work 
Field3 = 9000 
+0

由于'\ s'和'\ n'和'-r'只适用于某些seds,如果“字段2”包含任何数字,将会失败。 –

+0

添加'?'使得它更便于携带。如果你摆脱了这一点,并且将最终的RE段固定到行尾,我认为它会更好:'/^([0-9]+)\s+(.*)\s+([0-9] +)$'。你甚至可以将'[0-9]'s改为'\ S's,然后保证它可以在任何语言环境中工作,并且不再关心这些字段是否是数字:'/ ^(\ S + )\ S +(。*)\ S +(\ S +)$ /'。 –

+0

现在看起来不错,+1。事实上,我看到你没有固定最终的可再生能源部分,它仍然有效,所以你不需要第一个锚定。所有关于对称性.... :-)。 –

0

它不是完美的,但你可以尝试使用此awk

awk '{s=$1;e=$NF; $1=$NF=""; gsub(/^ +| +$/, ""); 
      printf "f1=<%s>,f2=<%s>,f3=<%s>\n", s, $0, e}' file 
f1=<4>,f2=<This is my test file>,f3=<4500> 
f1=<5>,f2=<This is test>,f3=<6000> 
f1=<6>,f2=<Not sure how it will work>,f3=<9000> 
+0

它很好用。我只是想引用第二个字段,所以我可以在它周围放置管道分隔符。谢谢。 – user3781132

+0

很高兴知道它解决了,你可以通过点击我答案左上角的勾号来接受答案。 – anubhava

+1

这个解决方案的唯一问题是,它将改变“字段2”中存在的任何空白,因此标签或空格序列将变成单个空格字符。 –

4

它几乎总是容易想出一个“解决方案”,适用于给定的示例输入集合,但很多要想出一个工作期。在选择“解决方案”之前真的想想你的现实可能的输入。如果输入中的字段少于3个,那么这个输出可能不会生成所需的输出,如果这可能会更新您的示例输入和预期输出以显示您希望如何处理。

$ awk '{ 
     f2=$0 
     gsub(/^[^[:space:]]+[[:space:]]+|[[:space:]]+[^[:space:]]+$/,"",f2) 
     print "field1 =", $1 
     print "field2 =", f2 
     print "field3 =", $NF 
}' file 
field1 = 4 
field2 = This is my test file 
field3 = 4500 
field1 = 5 
field2 = This is test 
field3 = 6000 
field1 = 6 
field2 = Not sure how it will work 
field3 = 9000 
+1

使用awk的好方案。 +1 – hwnd