Bash

bash:包含部分 AWK 程式碼的函式

  • October 28, 2020

在我的 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 腳本的開頭定義),然後將其用作腳本中的一行命令(在更複雜的 cas 中,它將應用於內部的許多填充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

只是改變 $ {file} to " $ 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。

如果你真的應該使用>>而不是>在結束時使用,那麼你可能想在函式之外進行輸出重定向。

引用自:https://unix.stackexchange.com/questions/616818