bash:包含部分 AWK 代码的函数

bash:包含部分 AWK 代码的函数

在我的 bash 代码中,我有一部分 sed + AWK 代码,它对输入文件进行交互一些操作并将结果添加到另一个 txt 文件中(这两个填充都是由相同的 bash 脚本创建的,并且可以存储为不同的变量)。

#sed removing some lines in input fille "${file}".xvg, defined in the begining of bash script
sed -i '' -e '/^[#@]/d' "${file}".xvg
# AWK measure XMAX and YMAX in the input file
# adding these outputs as two lines in another batch.bfile, which is going to be used for something
awk '
  NR==1{
    max1=$1
    max2=$2
  }
  $1>max1{max1=$1}
  $2>max2{max2=$2}
  END{printf "WORLD XMAX %s\nWORLD YMAX %s\n",max1+0.5,max2+0.5'} "${file}".xvg >> "${tmp}"/batch.bfile

是否可以将这两个 (sed +awk ) 操作组合成某个函数(在我的 bash 脚本的开头定义),然后将其用作脚本中的一行命令(在更复杂的情况下,它将应用于FOR 循环)?

这是我的版本的示例:

#!/bin/bash


#folder with batch file
home=$PWD
tmp="${home}"/tmp


## define some functions for file processing
bar_xvg_proc () {
##AWK procession of XVG file: only for bar plot;
sed -i '' -e '/^[#@]/d' ${file}
# check XMAX and YMAX for each XVG
awk '
  NR==1{
    max1=$1
    max2=$2
  }
  $1>max1{max1=$1}
  $2>max2{max2=$2}
  END{printf "WORLD XMAX %s\nWORLD YMAX %s\n",max1+0.5,max2+0.5'} ${file} >> "${tmp}"/grace2.bfile

}
###

bar_xvg_proc "${home}"/test.xvg

这是 sed 的错误

sed: -i may not be used with stdin

但是如果我在调用脚本中的函数之前将 test.xvg 定义为新变量 $file="${home}"/test.xvg - 它效果很好。我如何直接与输入文件一起使用此函数(没有分配给文件的特定变量)?

这是我的 xvg 文件:

# Created by:
#                     :-) GROMACS - gmx cluster, 2019.3 (-:
# 
# Executable:   /usr/local/bin/../Cellar/gromacs/2019.3/bin/gmx
# Data prefix:  /usr/local/bin/../Cellar/gromacs/2019.3
# Working dir:  /Users/gleb/Desktop/DO/unity_or_separation
# Command line:
# gmx cluster is part of G R O M A C S:
#
# Good gRace! Old Maple Actually Chews Slate
#
@    title "Cluster Sizes"
@    xaxis  label "Cluster #"
@    yaxis  label "# Structures"
@TYPE xy
@g0 type bar
       1       94
       2       31
       3       24
       4       24
       5       15
       6        6
       7        6
       8        5
       9        4
      10        4
      11        3
      12        3
      13        3
      14        3
      15        2
      16        2
      17        2
      18        2
      19        1
      20        1
      21        1
      22        1
      23        1
      24        1
      25        1

答案1

只需在函数内将 ${file} 更改为“$1”,它就会执行您想要的操作。

然后再考虑改变这一点:

bar_xvg_proc () {
##AWK procession of XVG file: only for bar plot;
sed -i '' -e '/^[#@]/d' "$1"
# check XMAX and YMAX for each XVG
awk '
  NR==1{
    max1=$1
    max2=$2
  }
  $1>max1{max1=$1}
  $2>max2{max2=$2}
  END{printf "WORLD XMAX %s\nWORLD YMAX %s\n",max1+0.5,max2+0.5'} "$1" >> "${tmp}"/grace2.bfile

}

对此:

bar_xvg_proc () {
    ##AWK procession of XVG file: only for bar plot;
    # check XMAX and YMAX for each XVG
    awk '
      /^[#@]/ { next }
      (++nr)==1{
        max1=$1
        max2=$2
      }
      $1>max1{max1=$1}
      $2>max2{max2=$2}
      END{printf "WORLD XMAX %s\nWORLD YMAX %s\n",max1+0.5,max2+0.5'} "${@:--}" >> "${tmp}"/grace2.bfile
}

当您使用 awk 时,您永远不需要 sed,并且使用"${@:--}"这种方式可以让您拥有一个函数,无论您向它传递多个文件名还是通过管道将流传递给它,它都可以工作,因为它告诉 awk 在不存在文件的情况下使用 stdin。

我不知道你是否真的应该使用>>而不是>在最后使用,并且你可能想在函数之外进行输出重定向。

相关内容