1

我不确定如何在nawk命令中实现函数调用。我已经从输入和输出中给出了我想要的范围。该函数应验证第 3 列并返回 true 或 false。如果列满足条件,那么它应该转到好文件;如果不去坏文件。您能帮我修改nawk命令以实现我的功能吗?

我知道我们可以在单个语句中实现长度验证,但我的验证函数只是示例代码。我想在验证功能中实现更多的长度检查。

输入.txt

1 | I | 123  | KK
3 | U | 3456 | JJ
6 | B | 241  | YH

输出好.txt

3 | U | 3456 | JJ

输出坏.txt

1 | I | 123  | KK
6 | B | 241  | YH

脚本:

#!/bin/sh
#function validation

function validate(){
in = $1
if length(in) > 3
  return true
else
 return false
}

nawk -F '|' 'function validate($3){print}' input.txt > outputgood.txt
4

2 回答 2

1

如果这是您读取的数据,则在管道上拆分将在字段值中留下空格。此外,nawk 函数实际上必须在 nawk 脚本的主体中。

让我们试试这个:

nawk -F'[[:space:]]*\\\|[[:space:]]*' '
    function validate(in) {
        return (length(in) > 3)
    }
    {
        if (validate($3)) {
            print > "good"
        } else {
            print > "bad"
        }
    }
' input.txt

更简单的是:

nawk -F '|' '{if ($3 > 1000) print > "good"; else print > "bad"}' input.txt
于 2014-03-30T19:07:25.340 回答
0

首先,你有一个 shell 函数,你试图从你的 awk 脚本中调用它。那是行不通的。

如果您的验证必须在 shell 中,那么也许您可以在 shell 中完成整个操作。

#!/bin/sh

while read line; do

  var=${line#* | }                              # take off first field
  var=${var#* | }                               # take off second field
  var=${var% | *}                               # take off fourth field
  var=`expr "$var" : "^\ *\(.*[^ ]\)\ *$"`      # trim whitespace

  if [ ${#var} -gt 3 ]; then
    echo "$line" >> outputgood.txt
  else
    echo "$line" >> outputbad.txt
  fi

done < input.txt

我们使用参数工具拆分行,因为$IFS不允许我们使用可变数量的空格。您也可以使用位置参数来执行此操作,这样您也可以更轻松地访问其他字段。请注意,如果您使用字段长度作为条件,您仍然需要修剪。

#!/bin/sh

IFS="|"
while read line; do

  set -- $line
  var=`expr "$3" : "^\ *\(.*[^ ]\)\ *$"`        # trim whitespace

  if [ ${#var} -gt 3 ]; then
    echo "$line" >> outputgood.txt
  else
    echo "$line" >> outputbad.txt
  fi

done < input.txt

如果您真正感兴趣的是第三个字段是否大于 1000,那么这将比字段的长度更好地测试。编程的清晰度就像其他任何事情的清晰度一样。如果可以避免,请不要混淆..

请注意,我们可以用更少的代码来做到这一点bash,但你的问题只是指定了“shell”,所以我假设/bin/sh

于 2014-03-30T20:01:53.903 回答