首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >补充模式

补充模式
EN

Stack Overflow用户
提问于 2012-01-05 08:22:46
回答 4查看 113关注 0票数 1

我在一个文件中有这样的记录:

代码语言:javascript
复制
1867    121 2 56 
1868    121 1 6 
1868    121 2 65 
1868    122 0 53 
1869    121 0 41 
1869    121 1 41 
1871    121 1 13 
1871    121 2 194

我想要获得以下输出:

代码语言:javascript
复制
1867    121 2 56 
1868    121 1 6 
1868    121 2 65 
1868    122 0 53 
1869    121 0 41 
1869    121 1 41 
1870    121 0 0
1871    121 1 13 
1871    121 2 194

不同之处在于1870 121 0 0行。

因此,如果第一列中的数字之间的差异大于1,那么我们必须包括一行缺少数字的行(上面的例子是1870)和其他列。应该以某种方式获取其他列,即让第二列是该列编号的可能值中的最小值(在本例中,这些值可能是121122),并且与第三列的情况相同。最后一列的值总是为零。

有人能给我提个建议吗?提前感谢!

我正在尝试用awk解决这个问题,但也许还有其他更好或更实用的解决方案……

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-05 08:39:21

像这样的东西可能行得通-

代码语言:javascript
复制
awk 'BEGIN{getline;a=$1;b=$2;c=$3}
NR==FNR{if (b>$2) b=$2; if (c>$3) c=$3;next} 
{if ($1-a>1) {x=($1-a); for (i=1;i<x;i++) {print (a+1)"\t"b,c,"0";a++};a=$1} else a=$1;print}' file file

解释:

  1. BEGIN{getline;a=$1;b=$2;c=$3} -

在这个BEGIN块中,我们读取第一行,并将column 1中的值赋给变量a,将column 2赋值给变量b,将column 3赋值给变量column 2-

在这里,我们扫描整个文件(NR==FNR),跟踪column 2column 3中可能的最低值,并将它们分别存储在变量bc中。我们使用next来避免运行第二个pattern{action}语句。

  • {if ($1-a>1) {x=($1-a); for (i=1;i<x;i++) {print (a+1)"\t"b,c,"0";a++};a=$1} else a=$1;print} -

action语句检查column 1中的值,并将其与a进行比较。如果差值大于1,我们将执行for loop以添加所有缺少的行,并将a的值设置为$1。如果连续行的column 1中的值不大于1,我们将column 1的值赋给a并对其执行print

测试:

代码语言:javascript
复制
[jaypal:~/Temp] cat file
1867    121 2 56 
1868    121 1 6 
1868    121 2 65 
1868    122 0 53 
1869    121 0 41 
1869    121 1 41 
1871    121 1 13  # <--- 1870 skipped
1871    121 2 194
1875    120 1 12 # <--- 1872, 1873, 1874 skipped

[jaypal:~/Temp] awk 'BEGIN{getline;a=$1;b=$2;c=$3}
NR==FNR{if (b>$2) b=$2; if (c>$3) c=$3;next} 
{if ($1-a>1) {x=($1-a); for (i=1;i<x;i++) {print (a+1)"\t"b,c,"0";a++};a=$1} else a=$1;print}' file file
1867    121 2 56 
1868    121 1 6 
1868    121 2 65 
1868    122 0 53 
1869    121 0 41 
1869    121 1 41 
1870    120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1871    121 1 13 
1871    121 2 194
1872    120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1873    120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1874    120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1875    120 1 12
票数 2
EN

Stack Overflow用户

发布于 2012-01-05 17:05:45

Perl解决方案。应该也适用于大文件,因为它不会将整个文件加载到内存中,而是对文件进行两次遍历。

代码语言:javascript
复制
#!/usr/bin/perl
use warnings;
use strict;

my $file = shift;

open my $IN, '<', $file or die $!;

my @mins;
while (<$IN>) {
    my @cols = split;
    for (0, 1) {
        $mins[$_] = $cols[$_ + 1] if $cols[$_ + 1] < $mins[$_ ]
                                     or ! defined $mins[$_];
    }
}

seek $IN, 0, 0;
my $last;
while (<$IN>) {
    my @cols = split;
    $last //= $cols[0];

    for my $i ($last .. $cols[0]-2) {
        print $i + 1, "\t@mins 0\n";
    }
    print;
    $last = $cols[0];
}
票数 1
EN

Stack Overflow用户

发布于 2012-01-05 21:37:27

Bash解决方案:

代码语言:javascript
复制
# initialize minimum of 2. and 3. column
read no min2 min3 c4 < "$infile"

# get minimum of 2. and 3. column
while read c1 c2 c3 c4 ; do
  [ $c2 -lt $min2 ] && min=$c2
  [ $c3 -lt $min3 ] && min=$c3
done < "$infile"

while read c1 c2 c3 c4 ; do
  # insert missing line(s) ?
  while (( c1- no > 1 )) ; do
    ((no++))
    echo -e "$no $min2 $min3 0"
  done
  # now insert existing line
  echo -e "$c1 $c2 $c3 $c4"
  no=$c1
done < "$infile"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8736039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档