【问题标题】:Unix shell - read array content in a for loopUnix shell - 在 for 循环中读取数组内容
【发布时间】:2013-05-12 10:00:56
【问题描述】:

这是我的数组:

orlist=""
orlist="T_TAB1 \n"
orlist=$orlist"T_TAB2 \n"
orlist=$orlist"T_TAB3 \n"
orlist=$orlist"T_TAB4 \n"
echo $orlist
arrIdx=0
OLD_IFS=$IFS;
IFS="\n"
for IndixList in ${orlist[@]};
do
     echo $IndxList
     MYDIR[${arraryIndix}]=$IndixList
    (( arraryIndix = $arraryIndix+ 1 ))
done
IFS=$OLD_IFS

我必须在 for 循环内的 oracle db 中执行 SELECT,因此我必须逐个选项卡读取 $orlist 选项卡。我已经尝试过了,但它不起作用,它需要整个数组而不是一个标签一个标签:

for arraryIndix in ${orlist[@]};
do

  echo "SET HEADING OFF"       >> ${FILEOR_SQL}
  echo "SET TERMOUT OFF"       >> ${FILEOR_SQL}
  echo "SET PAGESIZE 0"        >> ${FILEOR_SQL}
  echo "SET LINESIZE 1000"     >> ${FILEOR_SQL}
  echo "SET FEEDBACK OFF"      >> ${FILEOR_SQL}
  echo "SET TRIMSPOOL ON"      >> ${FILEOR_SQL}
  echo "SPOOL ${FILE_DAT}"     >> ${FILEOR_SQL}
  echo "SELECT * "             >> ${FILEOR_SQL}
  echo "FROM ${orlist[@]}"     >> ${FILEOR_SQL}
  echo "WHERE REP_ARG = 2; "   >> ${FILEOR_SQL}
  echo "SPOOL OFF"             >> ${FILEOR_SQL}
  echo "COMMIT;"               >> ${FILEOR_SQL}
  echo "SET HEADING ON"        >> ${FILEOR_SQL}
  echo "SET TERMOUT ON"        >> ${FILEOR_SQL}
  echo "SET PAGESIZE 14"       >> ${FILEOR_SQL}
  echo "SET FEEDBACK ON"       >> ${FILEOR_SQL}
  echo "SET TRIMSPOOL OFF"     >> ${FILEOR_SQL}
  echo "EXIT;"                 >> ${FILEOR_SQL}

  sqlplus -S -L ${Connection} @${FILEOR_SQL} #connection is a var for connect with `sqlplus`

done

有什么建议吗?提前致谢

【问题讨论】:

  • 你怎么不使用实际的数组?
  • 在什么意义上?对不起,我不明白你的问题
  • 在实际数组的意义上。 var=("element 1" "element 2")
  • 然后?for循环?
  • 但是我有一个错误:第 101 行的语法错误:`(' is not expected.

标签: arrays shell for-loop ksh


【解决方案1】:

不要多次调用 sqlplus,而是让 SQL 脚本包含所有查询:

cat < END1 > ${FILEOR_SQL}
SET HEADING OFF
SET TERMOUT OFF
SET PAGESIZE 0
SET LINESIZE 1000
SET FEEDBACK OFF
SET TRIMSPOOL ON
SPOOL ${FILE_DAT}
END1

orlist=(T_TAB1 T_TAB2 T_TAB3 T_TAB4)

for table in "${orlist[@]}"; do
    echo "SELECT * FROM $table WHERE REP_ARG = 2;" >> ${FILEOR_SQL}
done

echo "QUIT" >> ${FILEOR_SQL}
sqlplus -S -L ${Connection} @${FILEOR_SQL}

【讨论】:

    【解决方案2】:

    你的问题来了,因为如果你写\n,它不一定被视为一个新行,有人必须翻译\的序列,然后是n作为一个新行。在IFS="\n" 中也相同,IFS 需要设置为评估为换行符的值,而不是\n 的组合。 orlist 也是一个变量,您没有将它用作数组,并且在 for 循环中,它不会被视为数组。 我做了一些更改,它似乎工作正常

    #!/usr/local/bin/ksh
    orlist=""
    orlist="T_TAB1 \n"
    orlist=$orlist"T_TAB2 \n"
    orlist=$orlist"T_TAB3 \n"
    orlist=$orlist"T_TAB4 \n"
    echo  $orlist
    arrIdx=0
    OLD_IFS=$IFS;
    IFS=$'\n'
    #IFS=""
    arraryIndix=0
    for IndxList in `echo -e $orlist`
    do
         echo "Hello $IndxList "
         MYDIR[${arraryIndix}]=$IndxList
        ((arraryIndix++))
    done
    IFS=$OLD_IFS
    echo "Finally ${MYDIR[@]}"
    

    输出

    T_TAB1 \nT_TAB2 \nT_TAB3 \nT_TAB4 \n
    Hello T_TAB1
    Hello T_TAB2
    Hello T_TAB3
    Hello T_TAB4
    Finally T_TAB1  T_TAB2  T_TAB3  T_TAB4
    
    
    $ ksh --version
    version         sh (AT&T Research) 93t+ 2010-02-02
    

    更新以下 cmets

    FILEOR_SQL=""
    func() {
      echo "SET HEADING OFF"       >> ${FILEOR_SQL}
      echo "SET TERMOUT OFF"       >> ${FILEOR_SQL}
      echo "SET PAGESIZE 0"        >> ${FILEOR_SQL}
      echo "SET LINESIZE 1000"     >> ${FILEOR_SQL}
      echo "SET FEEDBACK OFF"      >> ${FILEOR_SQL}
      echo "SET TRIMSPOOL ON"      >> ${FILEOR_SQL}
      echo "SPOOL random     "     >> ${FILEOR_SQL}
      echo "SELECT * "             >> ${FILEOR_SQL}
      echo "FROM $1"               >> ${FILEOR_SQL}
      echo "WHERE REP_ARG = 2; "   >> ${FILEOR_SQL}
      echo "SPOOL OFF"             >> ${FILEOR_SQL}
      echo "COMMIT;"               >> ${FILEOR_SQL}
      echo "SET HEADING ON"        >> ${FILEOR_SQL}
      echo "SET TERMOUT ON"        >> ${FILEOR_SQL}
      echo "SET PAGESIZE 14"       >> ${FILEOR_SQL}
      echo "SET FEEDBACK ON"       >> ${FILEOR_SQL}
      echo "SET TRIMSPOOL OFF"     >> ${FILEOR_SQL}
      echo "EXIT;"
    }
    orlist=""
    orlist="T_TAB1 \n"
    orlist=$orlist"T_TAB2 \n"
    orlist=$orlist"T_TAB3 \n"
    orlist=$orlist"T_TAB4 \n"
    echo  $orlist
    OLD_IFS=$IFS;
    IFS=$'\n'
    arraryIndix=0;
    for IndxList in `echo -e $orlist`
    do
      FILEOR_SQL="testfilesql"$arraryIndix
      func $IndxList
      ((arraryIndix++))
    done
    IFS=$OLD_IFS
    

    【讨论】:

    • 您确定这种方式与 ksh 一致吗?因为我有语法错误
    • 嗯,好的。现在我的列表是逐行列出的。对于for循环?我该怎么做?
    • 我检查了 ksh,似乎工作正常,对不起,我不明白 list is a list line by line
    • 是的,但在我的输出之前是:T_TAB1 \nT_TAB2 \nT_TAB3 \nT_TAB4 \n 仅而不是逐行:)。问题是循环..似乎循环无法识别换行符..它在输出 sql 文件中标记了我整个数组: FROM T_TAB1 \nT_TAB2 \nT_TAB3 \nT_TAB4 \n 而不是来自第一个 cicle FROM TAB1 的第二个 FROM TAB2 等等等等。明白了吗?
    • 啊,是指第二​​个循环吗?这里第一次迭代应该用FROM T_TAB1 创建一个文件,第二个FROM T_TAB2 对吗?那么你已经在MYDIR 中准备好了数组,而不是for arraryIndix in ${orlist[@]}; 使用for arraryIndix in ${MYDIR[@]};
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-05-17
    • 2018-12-24
    • 2020-03-29
    • 2015-06-13
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多