unix bash:将特定列分成多个列

时间:2014-10-08 17:46:17

标签: bash unix

我有一个带有三列的制表符分隔文件。第3列中的每一行都包含一个包含4个名称的字符串,每个名称由空格('')分隔,但在某些情况下,名称之间分隔的空格不止一个。我想使用unix-bash命令行来打印第1列,第2列,name1,name2,name3,name4,name5,所有这些都由制表符分隔。

我想要的输出如下:

avov2323[tab]rogoc232[tab]Roy[tab]Don[tab]Mike[tab]Ned[tab]Lee
cdso3432[tab]fokfd543[tab]Tom[tab]Gil[tab]Rose[tab]Dan[tab]Sam
  • 有没有办法将我的所有第3列存储到变量中,然后根据空格拆分这个特定的变量? 就像是: a = awk -F "\t" '{print $3}' file.txt; awk -F“”'{print $ 1}'$ a;

虽然 - 这个命令行对我来说不起作用......因为第3列中的所有名称在$ a中都变得狭窄。

3 个答案:

答案 0 :(得分:3)

使用tr翻译:

tr <inputFile " " "\t" | tr -s "\t" >outputFile

修改 正如格伦杰克曼所指出的那样,最好先挤压空间,然后将剩下的空间改为标签。

tr <inputFile -s " " | tr " " "\t" >outputFile

但它仍然容易受到前两列空格的影响。

答案 1 :(得分:1)

你可以使用awk:

$ cat file
avov2323        rogoc232        Roy  Don Mike  Ned Lee
cdso3432        fokfd543        Tom Gil    Rose  Dan Sam
$ awk '{$1=$1}1' OFS='\t' file
avov2323        rogoc232        Roy     Don     Mike    Ned     Lee
cdso3432        fokfd543        Tom     Gil     Rose    Dan     Sam

$1=$1只需触摸每条记录,以便应用新的输出格式。 1的计算结果为true,因此每行都会打印出来。 Awk将任意数量的空白字符视为输入字段分隔符,如您所见,每个名称之间的空格数不是问题。

要覆盖原始文件,您可以使用临时文件:

awk '{$1=$1}1' OFS='\t' file > tmp && mv tmp file

答案 2 :(得分:1)

为了完整起见,我还写了一个awk oneliner,它不会触及前两列中的任何空格。它还保留了空列:

awk <inputFile -F '\t' 'BEGIN{OFS="\t"} {gsub(/ +/,OFS,$3); print $1,$2,$3}'

修改 关于评论中提到的改进 - 是的,可以拆分任何列,甚至是中间列,尽管需要更通用的脚本。然而,它不是一个oneliner,当放在一行时看起来很尴尬。我很确定它仍然可以进行一些优化。格式化:

BEGIN {
  FS=OFS="\t";
  splitAt=3;
}{
  gsub(/ +/,OFS,$splitAt);
  line=$1;
  for(i=2;i<splitAt;i++)
    line=line""OFS""$i;
  line=line""OFS""$splitAt;
  for(i=splitAt+1;i<=NF;i++)
    line=line""OFS""$i;
  print line;
}

负责人:

awk <inputFile 'BEGIN{FS=OFS="\t"; splitAt=2;} {gsub(/ +/,OFS,$splitAt); line=$1; for(i=2;i<splitAt;i++) line=line""OFS""$i; line=line""OFS""$splitAt; for(i=splitAt+1;i<=NF;i++) line=line""OFS""$i; print line ;}'

可以重构以提供splitAt作为脚本的参数。