【问题标题】:How to print multiple lines as field? [closed]如何将多行打印为字段? [关闭]
【发布时间】:2013-12-19 10:18:08
【问题描述】:

我的数据如下:

P04637 1A1U 1AIE 1C26 1DT7 1GZH 1H26 1HS5 1JSP 1KZY 1MA3 1OLG 1OLH 1PES 1PET 1SAE 1SAF 1SAK 1SAL 1TSR 1TUP 1UOL 1XQH 1YC5 1YCQ

但我想要如下:

P04637 1A1U
P04637 1C26
P04637 1AIE
P04637 1DT7
P04637 1XQH
P04637 1MA3
P04637 1PES
P04637 1SAE

【问题讨论】:

  • Perl 或 Awk.. 哪个?
  • 你试过什么?你有什么问题? StackOverflow 不是“为我编写代码”服务。
  • @DaveCross - 我无法理解对此的赞成票......没有做出任何努力,最初无法理解的非问题
  • 如何导出第2列?似乎它们不是按原始顺序排列的。
  • @ceving:如果问题措辞恰当并且可能与其他用户高度相关,您应该投票赞成。因为一个问题给你一个有趣的谜题而投票会破坏系统。

标签: perl awk


【解决方案1】:

这会打印第一个字段,然后打印每个后续字段,直到行尾。

$ awk '{for (i=2;i<=NF;i++) print $1,$i}' file                                 
P04637 1A1U
P04637 1AIE
P04637 1C26
P04637 1DT7
P04637 1GZH
P04637 1H26
P04637 1HS5
P04637 1JSP
P04637 1KZY
P04637 1MA3
P04637 1OLG
P04637 1OLH
P04637 1PES
P04637 1PET
P04637 1SAE
P04637 1SAF
P04637 1SAK
P04637 1SAL
P04637 1TSR
P04637 1TUP
P04637 1UOL
P04637 1XQH
P04637 1YC5
P04637 1YCQ

要准确获取 OP 请求,不多不少:

awk '{print $1,$2 RS $1,$4 RS $1,$3 RS $1,$5 RS $1,$23 RS $1,$11 RS $1,$14 RS $1,$16}' file
P04637 1A1U
P04637 1C26
P04637 1AIE
P04637 1DT7
P04637 1XQH
P04637 1MA3
P04637 1PES
P04637 1SAE

【讨论】:

  • 经典解决方案.. +1
  • 大家好,刚刚意识到原来的问题是要求随机导出,看看我的解决方案。 :-)
  • 你怎么能从 OP 文本中分辨出来。他可能写错了。输出请求中没有列出所有行,所以他可能只需要一些。这里的所有解决方案都是错误的。
  • @BMW 看我更新的帖子。
【解决方案2】:

awk 的另一种方法:

awk 'NR==1 {a=$1; next} {print a,$1}' RS=" " file

通过设置RS=" ",我们将行分隔符定义为空格。这样,我们每次都会获取不同的记录。

NR==1 表示正在读取第一条记录。在那里,我们存储第一个值。从那时起,我们继续写入保存的值 + 当前值。

返回:

P04637 1A1U
P04637 1AIE
P04637 1C26
P04637 1DT7
P04637 1GZH
P04637 1H26
P04637 1HS5
P04637 1JSP
P04637 1KZY
P04637 1MA3
P04637 1OLG
P04637 1OLH
P04637 1PES
P04637 1PET
P04637 1SAE
P04637 1SAF
P04637 1SAK
P04637 1SAL
P04637 1TSR
P04637 1TUP
P04637 1UOL
P04637 1XQH
P04637 1YC5
P04637 1YCQ

【讨论】:

  • 不错的一个 +1。我写了一个设置OFS,但留下一个空行。这样更好。
  • 大家好,刚刚意识到原始问题是要求随机导出,请参阅我的解决方案。 :-)
  • 好吧@BMW 我不会随便说。我想样本输出只是一个样本,有这个想法。作者的一些澄清可能会有所帮助。
【解决方案3】:
perl -lane '$v=shift @F; print "$v $_" for @F' file

【讨论】:

    【解决方案4】:
    perl -lane 'print "$F[0] $_" for(@F[1..$#F])'
    

    【讨论】:

      【解决方案5】:

      这项工作既不需要 Perl 也不需要 Awk。 bash 就足够了:

      { IFS=' ' read -r -a A ; for I in ${A[@]:1} ; do echo ${A[0]} $I ; done ; } <<<'P04637 1A1U 1AIE 1C26 1DT7 1GZH 1H26 1HS5 1JSP 1KZY 1MA3 1OLG 1OLH 1PES 1PET 1SAE 1SAF 1SAK 1SAL 1TSR 1TUP 1UOL 1XQH 1YC5 1YCQ'
      P04637 1A1U
      P04637 1AIE
      P04637 1C26
      ...
      

      你需要的都在这里了:

      【讨论】:

        【解决方案6】:

        作为 perl 脚本:

        use warnings;
        use strict; 
        
        open my $input, '<', 'in.txt' or die "$!";
        
        while (<$input>){
            my @split = split;
            my $spacer = shift @split;
            print "$spacer $_\n" foreach @split;
        }
        

        打印:

        P04637 1A1U
        P04637 1AIE
        P04637 1C26
        P04637 1DT7
        P04637 1GZH ... 
        

        【讨论】:

        • 他没有要求制表符。
        • @ceving - 他并没有真正要求任何东西。
        【解决方案7】:

        意识到原来的问题是要求随机导出

        awk 'BEGIN{srand($RANDOM)}
        { split($0,a,FS);
          for (i=2;i<=NF;i++) 
             { while (1) 
                 {  s=int(rand()*(NF-1)+2)
                    if (a[s]!="") {print $1,a[s];delete a[s];break}
                 }
             }
        }' file
        

        结果

        P04637 1C26
        P04637 1H26
        P04637 1DT7
        P04637 1HS5
        P04637 1AIE
        P04637 1GZH
        P04637 1A1U
        

        【讨论】:

        • 随机订购awk '{for(i=2;i&lt;=NF;i++)print $1,$i}' file | sort -R
        • 你为什么用14这个号码?而$RANDOM 将等于空字符串"" 我认为..
        • 你说得对,我已经更新到 NF-1。我之前做过 14 个项目的测试
        • 这个论坛很有趣,态度不好,人们给出错误的答案,获得投票,挑战他们但被拒绝的人。这里仍然是一个免费的地方,我会毫不畏惧地继续挑战他们。
        猜你喜欢
        • 2011-09-11
        • 1970-01-01
        • 2022-01-25
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-30
        相关资源
        最近更新 更多