将bash函数更改为awk

时间:2018-06-06 04:39:44

标签: shell unix awk

我的团队设计了以下功能。它在Bash。我必须为具有数十万条记录的文件调用此函数。这花费了太多时间。请有人建议我将以下功能更改为awk吗?

 data_mask() {

  col_val=$1
  l_ret_str=""
  l_an=0
  l_lp=0
  l_mod=0
  absnum=0
  austart=65
  auend=90
  aclsize=26
  alstart=97
  alend=122
  nstart=48
  nend=57
  nclsize=10

  l_lp=`expr length "$col_val"`
  if [[ $l_lp -ne 0 ]]; then
    for i in `eval "echo {1..$l_lp}"`
    do
      single_char=$(SUBSTR "$col_val" $i)
      ascii_num_val=$(ASCII "$single_char")
      l_mod=$((l_mod+ascii_num_val))
    done

    l_mod=$((l_mod % nclsize))

    for i in `eval "echo {1..$l_lp}"`
    do
      single_char=$(SUBSTR "$col_val" $i)
      ascii_num_val=$(ASCII "$single_char")
      l_an=$ascii_num_val
      tempvar=$((l_an - l_lp - l_mod - i))
      absnum=$(ABS $tempvar)
      if [[ $l_an -ge $austart && $l_an -le $auend ]]; then
        tempmodval=$((absnum % aclsize))
        tempasciival=$((austart + tempmodval))
        l_ret_str=$l_ret_str$(CHR $tempasciival)
      elif [[ $l_an -ge $alstart && $l_an -le $alend ]]; then
        tempmodval=$((absnum % aclsize))
        tempasciival=$((alstart + tempmodval))
        l_ret_str=$l_ret_str$(CHR $tempasciival)
      elif [[ $l_an -ge $nstart && $l_an -le $nend ]]; then
        tempmodval=$((absnum % nclsize))
        tempasciival=$((nstart + tempmodval))
        l_ret_str=$l_ret_str$(CHR $tempasciival)
      else
        tempmodval=$((absnum % nclsize))
        tempasciival=$((austart + tempmodval))
        l_ret_str=$l_ret_str$(CHR $tempasciival)
      fi

    done
  fi
  echo "$l_ret_str"
}

我通过使用以下登录来调用此函数。我必须将其称为特定列。该列由用户输入。所以我将字符串拆分为3个部分。

  while read p; do

  if [[ $line -le $skip_line ]]; then
    echo "$p" >> $outputfile
  else
    pre_str=`echo $p | cut -d'|' -f1-$((colnum - 1))`
    column_value=`echo $p | cut -d'|' -f$colnum`
    post_str=`echo $p | cut -d'|' -f$((colnum + 1))-$totalcol`
    echo "column_value=$column_value"
    maskvalue=$(data_mask "$column_value")
    #echo $pre_str"|"$maskvalue"|"$post_str >> $outputfile
#    awk -v col=2 'BEGIN { FS=OFS="|" } col<=NF { $col = data_mask(" $col ") } 1' $temp_outputfile >>123.txt
     awk -v col=3 'BEGIN { FS=OFS="|" } col<=NF { $col = $maskvalue; print }' $temp_outputfile >123.txt
#     awk -F"|" -vOFS="|" 'NR==1{$3=100} {print}' file
  fi

  line=$((line + 1))

  done < $file

有人可以建议我做些优化​​吗?

1 个答案:

答案 0 :(得分:1)

试试这个:

awk -v col=3 'col<=NF { $col = "FUNCTION(" $col ")" } 1' file

您可以轻松地将分隔符更改为管道:

awk -v col=3 'BEGIN { FS=OFS="|" } col<=NF { $col = "FUNCTION(" $col ")" } 1' file

这适用于任何AWK。