linux中的while循环问题

时间:2017-12-03 07:10:03

标签: linux bash shell

以下所有人都是我的文本文件中的数据

DEC/08/2017 00:00:00|DEC/03/2017 00:00:00|ALL|ALL|Testing ALL condition|G800162|Y|12
NOV/08/2017 22:37:00|NOV/09/2017 00:38:00|SWETR|ARETC|CRQ changes.|G800162|Y|11
NOV/08/2017 23:30:00|NOV/09/2017 00:15:00|PHLSR|ARETC|Customer connectivity issue|G800162|Y|35
NOV/18/2017 00:29:00|NOV/19/2017 11:10:00|ABWSE|GBRVF|Checking Update from Script.|G800162|Y|12
NOV/08/2017 22:47:00|NOV/09/2017 00:37:00|ALL|ALL|Testing VPMN and HPMN as ALL|G800162|Y|12
NOV/08/2017 20:46:00|NOV/08/2017 21:30:00|ALL|ARETC|Checking with 8th Date|G800162|Y|16
NOV/08/2017 20:47:00|NOV/08/2017 22:30:00|ALL|ARETC|Checking with 8th Date|G800162|Y|12
NOV/19/2017 10:38:00|NOV/19/2017 12:03:00|KWTKT|ALL|testing if condition.|G800162|Y|26
NOV/08/2017 22:40:00|NOV/09/2017 00:36:00|ALL|ARETC|Testing IF COND|G800162|Y|12

我正在使用IFS分隔字段并使用cut命令将值传递给变量。直到传递变量一切都很好。如果条件VPMNHPMN都是ALL,那么只有下面的更新查询才会执行。我看到是否满足任何一个条件更新查询正在执行。

while IFS='|' read -r row || [[ -n $row ]];
do
[ -z "$row" ] && continue

IN_TIME=`echo $row |cut -d'|' -f1`
OUT_TIME=`echo $row |cut -d'|' -f2`
VPMN=`echo $row |cut -d'|' -f3`
HPMN=`echo $row |cut -d'|' -f4`
REMARKS=`echo $row |cut -d'|' -f5`
USER_ID=`echo $row |cut -d'|' -f6`
EXCLUSION_FLAG=`echo $row |cut -d'|' -f7`
EXCLUDE_CODE=`echo $row |cut -d'|' -f8`
if ( VPMN="ALL"  &&  HPMN="ALL" )
then
echo "update  XXXXXX.YYYYYY set remarks='$REMARKS',user_id='$USER_ID',exclusion_flag='$EXCLUSION_FLAG',exclude_code='$EXCLUDE_CODE' where  out_time between to_date('$IN_TIME','MON/DD/YYYY HH24:MI:SS') and to_date('$OUT_TIME','MON/DD/YYYY HH24:MI:SS'); " >updatenrtpmnsql.sql
fi

完成

4 个答案:

答案 0 :(得分:1)

cutIFS一起使用有点尴尬。使用数组和IFS代替:

while IFS='|' read -ra cols; do
  in_time=${cols[0]}
  out_time=${cols[1]}
  vpmn=${cols[2]}
  hpmn=${cols[3]}
  if [[ "$vpmn" == "ALL" ]] && [[ "$hpmn" == "ALL" ]]; then echo "$vpmn:$hpmn"; fi
done < input_file

答案 1 :(得分:0)

您完全没有设置IFS进行读取,因为您没有使用它来分隔字段。你的意思是:

while IFS='|' read in_time out_time vpmn hpmn remarks user_id exclusion_flag exclude_code; do ...

答案 2 :(得分:0)

条件if ( VPMN="ALL" && HPMN="ALL" )在使用

方面是错误的
  1. 使用错误的运算符进行字符串比较(..)不是为在子shell中运行操作定义的构造。
  2. 变量VPMNHPMN未在比较中使用,您在语句中执行的操作是将值分配给if条件中的那些变量始终是真的。您需要检查这些变量的值。
  3. 你的病情需要像,

    if [ "$VPMN" = "ALL" ] && [ "$HPMN" = "ALL" ]
    

    除当前主题外,用户定义变量的小写名称始终不与系统环境变量混淆。

答案 3 :(得分:0)

( VPMN="ALL" && HPMN="ALL" )不是条件,而是子shell 。 此子shell始终以状态0退出, 当在if中使用时,条件总是计算为true, 导致你正在观察的行为。

像这样写:

if [[ $VPMN = "ALL" ]] && [[ $HPMN = "ALL" ]]

此外,循环效率极低, 因为它为每列运行cut进程。 使用read本身可以大大改善它, 将列直接存储在正确的变量中, 感谢给定的IFS

while IFS='|' read -r in_time out_time vpmn hpmn remarks user_id exclusion_flag exclude_code _; do
    [[ $in_time ]] || continue

    if [[ $vpmn = ALL ]] && [[ $hpmn = ALL ]]
    then
        echo "update  XXXXXX.YYYYYY set remarks='$remarks',user_id='$user_id',exclusion_flag='$exclusion_flag',exclude_code='$exclude_code' where  out_time between to_date('$in_time','MON/DD/YYYY HH24:MI:SS') and to_date('$out_time','MON/DD/YYYY HH24:MI:SS'); "
    fi
done

请注意,我将SHOUT_CASE中的所有变量重命名为小写, 因为这是推荐的做法。 SHOUT_CASE是系统变量的约定(通过POSIX标准)。