【问题标题】:How to run command line awk script (with arguments) as bash script?如何将命令行 awk 脚本(带参数)作为 bash 脚本运行?
【发布时间】:2021-05-02 18:49:48
【问题描述】:

我有一个 awk 脚本 (tst.awk):

NR==FNR {
    ids[++numIds] = $1","
    next
}
FNR==1 { numFiles++ }
{
    id = $1
    sub(/^[^[:space:]]+[[:space:]]+/,"")
    vals[id,numFiles] = $0
    gsub(/[^[:space:],]+/,"NA")
    naVal[numFiles] = $0
}
END {
    for ( idNr=1; idNr<=numIds; idNr++) {
        id = ids[idNr]
        printf "%s%s", id, OFS
        for (fileNr=1; fileNr<=numFiles; fileNr++) {
            val = ((id,fileNr) in vals ? vals[id,fileNr] : naVal[fileNr])
            printf "%s%s", val, (fileNr<numFiles ? OFS : ORS)
        }
    }
}

在命令行中调用:

awk -f tst.awk master file1 file2 file3 > output.file

(注意:参数的数量可以不定)

如何更改此脚本和命令行代码以将其作为 bash 脚本运行?

我试过了(tst_awk.sh):

#!/bin/bash

awk -f "$1" "$2" "$3" "$4"

'NR==FNR {
        ids[++numIds] = $1","
        next
    }
    FNR==1 { numFiles++ }
    {
        id = $1
        sub(/^[^[:space:]]+[[:space:]]+/,"")
        vals[id,numFiles] = $0
        gsub(/[^[:space:],]+/,"NA")
        naVal[numFiles] = $0
    }
    END {
        for ( idNr=1; idNr<=numIds; idNr++) {
            id = ids[idNr]
            printf "%s%s", id, OFS
            for (fileNr=1; fileNr<=numFiles; fileNr++) {
                val = ((id,fileNr) in vals ? vals[id,fileNr] : naVal[fileNr])
                printf "%s%s", val, (fileNr<numFiles ? OFS : ORS)
            }
        }
    }' > output_file

在命令行调用:

./tst_awk.sh master file1 file2 file3

我也试过(tst_awk2.sh):

#!/bin/bash

awk -f master file1 file2 file3

'NR==FNR {
        ids[++numIds] = $1","
        next
    }
    FNR==1 { numFiles++ }



...

        }
    }
}' > output_file

在命令行调用:

./tst_awk2.sh

【问题讨论】:

  • 使用awk '...' master file1 file2 file3 &gt; output.file(将...替换为tst.awk中的awk脚本)

标签: bash awk


【解决方案1】:

-f 后面需要跟awk 脚本的名称。您将 shell 脚本的第一个参数放在它之后。

您可以使用 "$@" 获取所有脚本参数,因此您不仅限于 4 个参数。

#!/bin/bash

awk -f /path/to/tst.awk "$@" > output_file

使用 awk 脚本的绝对路径,以便您可以从任何目录运行 shell 脚本。

如果您不想使用单独的tst.awk,只需将脚本作为文字的第一个参数传递给awk

#!/bin/bash

awk 'NR==FNR {
        ids[++numIds] = $1","
        next
    }
    FNR==1 { numFiles++ }
    {
        id = $1
        sub(/^[^[:space:]]+[[:space:]]+/,"")
        vals[id,numFiles] = $0
        gsub(/[^[:space:],]+/,"NA")
        naVal[numFiles] = $0
    }
    END {
        for ( idNr=1; idNr<=numIds; idNr++) {
            id = ids[idNr]
            printf "%s%s", id, OFS
            for (fileNr=1; fileNr<=numFiles; fileNr++) {
                val = ((id,fileNr) in vals ? vals[id,fileNr] : naVal[fileNr])
                printf "%s%s", val, (fileNr<numFiles ? OFS : ORS)
            }
        }
    }' "$@" > output_file

【讨论】:

  • 非常好!并感谢您提供更多信息。第一次看到“$@”。
【解决方案2】:

您可以通过添加 shebang 使您的 awk 脚本可执行

#! /bin/awk -f

NR==FNR {
   ids[++numIds] = $1","
   next
}...

别忘了chmod +x tst.awk 并运行

$ ./tst.awk  master file1 file2 file3 > outfile

【讨论】:

猜你喜欢
  • 2023-01-18
  • 2018-08-28
  • 2012-06-25
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多