Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 补充模式_Linux_Bash_Shell_Awk - Fatal编程技术网

Linux 补充模式

Linux 补充模式,linux,bash,shell,awk,Linux,Bash,Shell,Awk,我在一个文件中有这样的记录: 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 我希望获得以下输出: 1867 121 2 56 1868 121 1 6 1868 121 2 65 1868 122 0 53 1869 1

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

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
我希望获得以下输出:

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

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

有人能给我提些建议吗?提前谢谢


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

类似的方法可以奏效-

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

像这样的东西可能有用-

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

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

#!/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];
}
#/usr/bin/perl
使用警告;
严格使用;
我的$file=shift;

打开我的$IN,“Perl解决方案。应该也适用于大文件,因为它不会将整个文件加载到内存中,而是对文件进行两次检查

#!/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];
}
#/usr/bin/perl
使用警告;
严格使用;
我的$file=shift;
在Bash解决方案中打开我的$IN,

# 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"
#至少初始化2个。三,。柱
阅读编号为min2 min3 c4的<$infle“
#至少得到2个。三,。柱
读取c1 c2 c3 c4时;做
[$c2-lt$min2]&&min=$c2
[$c3-lt$min3]&&min=$c3
完成<“$infle”
读取c1 c2 c3 c4时;做
#是否插入缺少的行?
而((c1-no>1));做
((no++)
echo-e“$no$min2$min3 0”
完成
#现在插入现有行
回声-e“$c1$c2$c3$c4”
否=$c1
完成<“$infle”
Bash解决方案:

# 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"
#至少初始化2个。三,。柱
阅读编号为min2 min3 c4的<$infle“
#至少得到2个。三,。柱
读取c1 c2 c3 c4时;做
[$c2-lt$min2]&&min=$c2
[$c3-lt$min3]&&min=$c3
完成<“$infle”
读取c1 c2 c3 c4时;做
#是否插入缺少的行?
而((c1-no>1));做
((no++)
echo-e“$no$min2$min3 0”
完成
#现在插入现有行
回声-e“$c1$c2$c3$c4”
否=$c1
完成<“$infle”

单向使用
awk

BEGIN { 
        if ( ARGC > 2 ) {
                print "Usage: awk -f script.awk <file-name>"
                exit 0
        }

        ## Need to process file twice, duplicate the input filename.
        ARGV[2] = ARGV[1]
        ++ARGC

        col2 = -1
        col3 = -1
}

## First processing of file. Get min values of second and third columns.
FNR == NR {
        col2 = col2 < 0 || col2 > $2 ? $2 : col2
        col3 = col3 < 0 || col3 > $3 ? $3 : col3
        next
}

## Second processing of file.
FNR < NR {
        ## Get value of column 1 in first row.
        if ( FNR == 1 ) {
                col1 = $1
                print
                next
        }

        ## Compare current value of column 1 with value of previous row.
        ## Add a new row while difference is bigger than '1'.
        while ( $1 - col1 > 1 ) {
                ++col1
                printf "%d\t%d %d %d\n", col1, col2, col3, 0
        }

        ## Assing new value of column 1.
        col1 = $1
        print
}
结果:

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

单向使用
awk

BEGIN { 
        if ( ARGC > 2 ) {
                print "Usage: awk -f script.awk <file-name>"
                exit 0
        }

        ## Need to process file twice, duplicate the input filename.
        ARGV[2] = ARGV[1]
        ++ARGC

        col2 = -1
        col3 = -1
}

## First processing of file. Get min values of second and third columns.
FNR == NR {
        col2 = col2 < 0 || col2 > $2 ? $2 : col2
        col3 = col3 < 0 || col3 > $3 ? $3 : col3
        next
}

## Second processing of file.
FNR < NR {
        ## Get value of column 1 in first row.
        if ( FNR == 1 ) {
                col1 = $1
                print
                next
        }

        ## Compare current value of column 1 with value of previous row.
        ## Add a new row while difference is bigger than '1'.
        while ( $1 - col1 > 1 ) {
                ++col1
                printf "%d\t%d %d %d\n", col1, col2, col3, 0
        }

        ## Assing new value of column 1.
        col1 = $1
        print
}
结果:

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

您可以尝试使用python脚本解决此问题,以获得“更好”的解决方案。您可以尝试使用python脚本解决此问题,以获得“更好”的解决方案。我的新年决心…
Learn Perl
:)…测试了您的脚本,效果非常好+1我的新年决心…
学习Perl
:)…测试了您的脚本,效果非常好+1你能不能把你的内部代码while减少到
while((c1 no>1));做。祝大家好运。难道你不能把你的内部代码while减少到
while((c1no>1));做。祝大家好运。