提取与最后一列中的最小值对应的行

时间:2017-04-03 10:44:46

标签: awk

我需要帮助从最后一列中具有最小编号的文件中提取所有行,即在这种情况下为7。

示例文件如下:

文件-1.txt的

WHEN EXTRACT(month FROM ? + INTERVAL '1 day') > EXTRACT(month FROM ?)

在这里,我想提取所有具有7的行,这是最后一列中的最小值(最小值),并通过仅提取[]中包含的值将输出保存到另一个文件File-2.txt中,如下图所示。

文件-2.txt

VALID_PATH :  [102, 80, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 81, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 56, 23, 125, 111]  7
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 111] 8
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 111]  8
VALID_PATH :  [102, 80, 112, 109, 23, 125, 110, 111]    8
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 111] 9
VALID_PATH :  [102, 80, 127, 88, 112, 109, 23, 125, 111]    9
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 110, 111]    9
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 110, 111] 9
VALID_PATH :  [102, 80, 127, 6, 112, 37, 109, 23, 125, 111] 10
VALID_PATH :  [102, 80, 127, 6, 112, 37, 56, 23, 125, 111]  10
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 110, 111]    10

我可以使用awk来获得最低价值" 7"从最后一列使用如下代码:

102, 80, 112, 109, 23, 125, 111
102, 81, 112, 109, 23, 125, 111
102, 112, 37, 109, 23, 125, 111
102, 112, 37, 56, 23, 125, 111

并且仅使用方括号[]中的值打印,使用以下awk代码:

awk 'BEGIN{getline;min=max=$NF}
NF{
    max=(max>$NF)?max:$NF
    min=(min>$NF)?$NF:min
}
END{print min,max}' File-1.txt

但是,我被困在分配从第一个awk脚本获得的最小值,即在这种情况下为7,以提取[]中包含的相应数字,如File-2.txt所示。

我们将非常感谢您解决此问题的任何帮助。

5 个答案:

答案 0 :(得分:2)

使用sort作为帮助来获取整洁的代码:

$ sort -t\] -nk 2 your_file |awk '$NF!=L && L{exit}{L=$NF;print $2}' FS='[][]'
102, 112, 37, 109, 23, 125, 111
102, 112, 37, 56, 23, 125, 111
102, 80, 112, 109, 23, 125, 111
102, 81, 112, 109, 23, 125, 111

答案 1 :(得分:2)

读取一次(例如:用于流媒体/管道信息),内存使用最少

awk -F'[][]' '
   # init counter
   NR == 1 { m = $3 + 1 }

   # add or replace content into the buffer if counter is lower or equal
   $3 <= m { b = ( $3 == m ? b "\n" : "" ) $2; m = $3 }

   # at the end, print buffer
   END { print b }
   ' YourFile

答案 2 :(得分:1)

@Asha:@try:

awk '{
Q=$NF;                    ##### Making last field of Input_file as NULL.
gsub(/.*\[|\]/,"");       ##### Using global substitution functionality of awk to remove everything till [ and then remove ] from the line as per your required output.
$NF="";                   ##### Nullifying the last column of each line as you don't need them in your output.
A[Q]=A[Q]?A[Q] ORS $0:$0; ##### creating an array named A whose index is Q variable(whose value is already assigned previously to last column), creating array A with index Q and concatenating it's value in itself.
MIN=MIN<Q?(MIN?MIN:Q):Q}  ##### Creating a variable named MIN(to get the minimum last value of each line) and comparing it's value to each line's last field and keeping the minimum value in it as per requirement.
END{print A[MIN]}         ##### In end block of code printing the value of array A whose index is variable MIN to print all the lines whose index is variable named MIN.
' Input_file              ##### Mentioning the Input_file here.

也会很快添加说明。

编辑:以下是相同的说明。

function observeModalName() {
  var save = $('#modalSaveName');
  $('#modalNewName').off('keyup').on('keyup', function() {
    var self = $(this);
    if (self.val().length < 5) {
      save.disable();
      self.error({message: 'Name must be at least 5 characters long'});
    } else {
      save.enable();
      self.error('remove');
    }
  });
}

答案 3 :(得分:1)

读取相同的文件两次,而不是使用array几乎慢一点,因为我们读取文件2次,但内存开销为零。

awk -F'[][]' 'FNR==NR{if(min > $NF || min==""){ min=$NF} next }
     $NF==min{ print $2 }' file file

<强>解释

awk -F'[][]' 'FNR==NR{                           # This block we read file 
                                                 # and will find whats minimum                                                 
             if(min > $NF || min==""){ 
                min=$NF                          # NF gives no of fields, assign the value of $NF to variable min 
             } 
              next 
     }
     $NF==min{                                   # Here we read file 2nd time, if last field value is equal to minimum
              print $2 
     }' file file

<强>输入

$ cat file
VALID_PATH :  [102, 80, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 81, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 56, 23, 125, 111]  7
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 111] 8
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 111]  8
VALID_PATH :  [102, 80, 112, 109, 23, 125, 110, 111]    8
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 111] 9
VALID_PATH :  [102, 80, 127, 88, 112, 109, 23, 125, 111]    9
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 110, 111]    9
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 110, 111] 9
VALID_PATH :  [102, 80, 127, 6, 112, 37, 109, 23, 125, 111] 10
VALID_PATH :  [102, 80, 127, 6, 112, 37, 56, 23, 125, 111]  10
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 110, 111]    10

<强>输出

$ awk -F'[][]' 'FNR==NR{ if(min > $NF || min==""){ min=$NF } next }
       $NF==min{ print $2 }' file file
102, 80, 112, 109, 23, 125, 111
102, 81, 112, 109, 23, 125, 111
102, 112, 37, 109, 23, 125, 111
102, 112, 37, 56, 23, 125, 111

答案 4 :(得分:1)

$ awk -F'[][]' -vmin=99999 '$NF<=min{min=$NF;print $2}'
  1. -F'[][]'将FS设置为regexp [][],表示&#34;或[或]&#34;,即您的输入字符串将在3个字段中分割。
  2. -vmin=99999将变量min设置为99999。在这个变量中将存储最后一个字段的最小值
  3. $NF <= min {min = $NF; print $2}如果当前最后一个字段小于或等于然后存储在变量min中, 然后更新min,并输出我们需要的内容。