如何在bash中使用多个参数并将它们传递给awk?

VIP*_*MAR 5 unix bash awk arguments function

我正在编写一个函数,我在其中替换列中的前导/尾随空格,如果列中没有值,则将其替换为null.函数适用于一列,但我如何修改多列.

功能:

#cat trimfunction
#!/bin/bash
function trim
{
vCol=$1                                                    ###input column name
vFile=$2                                                   ###input file name
var3=/home/vipin/temp                                      ###temp file
awk -v col="${vCol}" -f /home/vipin/colf.awk ${vFile} > $var3 ###operation
mv -f $var3 $vFile                                         ###Forcefully mv
}
Run Code Online (Sandbox Code Playgroud)

AWK脚本:

#cat colf.awk
#!/bin/awk -f
BEGIN{FS=OFS="|"}{
  gsub(/^[ \t]+|[ \t]+$/, "", $col)                        ###replace space from 2nd column
}
{if ($col=="") {print $1,"NULL",$3} else print $0}         ###replace whitespace with NULL
Run Code Online (Sandbox Code Playgroud)

输入文件:第二列中的前导/尾随/空格

#cat filename.txt
1| 2016-01|00000321|12
2|2016-02 |000000432|13
3|2017-03 |000004312|54
4|  |000005|32
5|2017-05|00000543|12
Run Code Online (Sandbox Code Playgroud)

脚本:

#cat script.sh

    . /home/vipin/trimfunction
    trim 2 filename.txt
Run Code Online (Sandbox Code Playgroud)

输出文件:第二列中删除了前导/尾随/空格

#./script.sh
#cat filename.txt
1|2016-01|00000321|12
2|2016-02|000000432|13
3|2017-03|000004312|54
4|NULL|000005
5|2017-05|00000543|12
Run Code Online (Sandbox Code Playgroud)

如果输入文件如下所示 - (文件的第2和第5列中的白色/前导/尾随空格)

1|2016-01|00000321|12|2016-01 |00000
2|2016-02 |000000432|13| 2016-01|00000
3| 2017-03|000004312|54|  |00000
4|  |000005|2016-02|0000
5|2017-05 |00000543|12|2016-02 |0000
Run Code Online (Sandbox Code Playgroud)

如何在输出下面执行 - (修剪所有前导/尾随空格,在第2和第5列中用空格替换空格)类似于trim 2 5 filename.txt trim 2 5 filename.txt ###将两列名称作为输入

1|2016-01|00000321|12|2016-01|00000
2|2016-02|000000432|13|2016-01|00000
3|2017-03|000004312|54|NULL|00000
4|NULL|000005|2016-02|0000
5|2017-05|00000543|12|2016-02|0000
Run Code Online (Sandbox Code Playgroud)

Ed *_*ton 4

这将完成你所说的你想要的:

$ cat tst.sh
file="${!#}"
cols=( "$@" )
unset cols[$(( $# - 1 ))]

awk -v cols="${cols[*]}" '
BEGIN {
    split(cols,c)
    FS=OFS="|"
}
{
    for (i in c) {
        gsub(/^[[:space:]]+|[[:space:]]+$/,"",$(c[i]))
        sub(/^$/,"NULL",$(c[i]))
    }
    print
}' "$file"

$ ./tst.sh 2 5 file
1|2016-01|00000321|12|2016-01|00000
2|2016-02|000000432|13|2016-01|00000
3|2017-03|000004312|54|NULL|00000
4|NULL|000005|2016-02|0000
5|2017-05|00000543|12|2016-02|0000
Run Code Online (Sandbox Code Playgroud)

但如果您真正想要的是对所有字段而不是特定字段进行操作,那么当然有一个更简单的解决方案。

cmd file > tmp; mv tmp file顺便说一句,永远不要这样做,cmd file > tmp && mv tmp file而是总是这样做(请注意&&),因此只有在命令成功时才覆盖原始文件。另外 - 始终引用您的 shell 变量,除非您有非常具体的目的而不这样做,并且完全理解所有含义,所以使用"$file",而不是$file。去谷歌上查询。