bash for循环,带空格的字符串

时间:2015-01-16 10:29:02

标签: arrays bash for-loop

cat file.txt

ob_No  ob_kind  ob_value  ob_lat   ob_lon   ob_depth  ob_time   
1      S        36.045    44.1432  12.5701  1.6       201303210000  
2      S        37.148    44.1432  12.5701  8.5       201303210000  
3      S        36.069    44.1432  12.5701  1.6       201303210029  
4      S        37.117    44.1432  12.5701  8.5       201303210029  
5      S        36.105    44.1432  12.5701  1.6       201303210100  
6      S        37.136    44.1432  12.5701  8.5       201303210100  
7      S        36.143    44.1432  12.5701  1.6       201303210130  
8      S        37.081    44.1432  12.5701  8.5       201303210130  
9      S        36.162    44.1432  12.5701  1.6       201303210159  

mapfile -s 1 -t ArrayObs < file.txt

我得到第1到9行的数组。

for  oline in ${ArrayObs[@]};do
  varDP=`echo ${oline} | awk '{print $6}'`
     if [ "${ArrayObs[0]}" == "$oline" ]; then
      valuesMO=`echo ${oline}`
      echo -e " first time"
      awk '{printf ("%.3f\n", $6)}' valuesMO > MkDepth
    else
      echo -e " not the first time"
      valuesMO=`echo ${oline}`
      awk '{printf ("%.3f\n", $6)}' valuesMO >> MkDepth
    fi
  done

我希望在第一次迭代时连接并附加其余的迭代。 if循环给出了致命错误(awk),因为字符串中有空格。 谢谢,

2 个答案:

答案 0 :(得分:1)

我将提供一个逐行读取文件的脚本;每一行都是一个数组,它将在数组上逐个值迭代。希望它有所帮助。


<强> file.txt的

ob_No  ob_kind  ob_value  ob_lat   ob_lon   ob_depth  ob_time   
1      S        36.045    44.1432  12.5701  1.6       201303210000  

<强>脚本

#!/usr/bin/env bash
# author    : Daniel Leybovich
# SO        : http://stackoverflow.com/questions/27981928/bash-for-loop-strings-with-spaces

FILE=${1}

while read LINE
do
    declare -a ROW

    ROW=($(echo ${LINE}))
    COLS=${#ROW[@]}

    echo "LINE    : .... ${LINE}"
    echo "COLS NUM: .... ${COLS}"
    echo "----------------------"
    echo "value by value:       "

    for INDEX in $(seq 0 $((COLS - 1)))
    do
        echo -e "\tCOL[${INDEX}] = ${ROW[${INDEX}]}"
    done

    echo '========================================='

done < ${FILE}

exit 0

<强>输出

daniel@synapse:/tmp$ ./so27981928.sh file.txt
LINE    : .... ob_No  ob_kind  ob_value  ob_lat   ob_lon   ob_depth  ob_time
COLS NUM: .... 7
----------------------
value by value:   
    COL[0] = ob_No
    COL[1] = ob_kind
    COL[2] = ob_value
    COL[3] = ob_lat
    COL[4] = ob_lon
    COL[5] = ob_depth
    COL[6] = ob_time
=========================================
LINE    : .... 1      S        36.045    44.1432  12.5701  1.6       201303210000
COLS NUM: .... 7
----------------------
value by value:   
    COL[0] = 1
    COL[1] = S
    COL[2] = 36.045
    COL[3] = 44.1432
    COL[4] = 12.5701
    COL[5] = 1.6
    COL[6] = 201303210000
=========================================

编辑[次要脚本改进]

#!/usr/bin/env bash
# author        : Daniel Leybovich

# create a temporary file
TABLE=$(mktemp)

# populate file with tabular data
cat << EOF >> ${TABLE}
col1    col2    col3    col4
[0,0]   [0,1]   [0,2]   [0,3]
[1,0]   [1,1]   [1,2]   [1,3]
EOF

# count line numbers
declare -i LN=0

# iterate over matrix rows 
while read LINE; do
    echo "-------------------------------------------------------------------"

    declare -a ROW

    ROW=(${LINE})
    COLS=${#ROW[@]}

    echo "LINE NO# ....... ${LN}"
    echo "COLUMNS  ....... ${LINE}"
    echo "COLUMNS NUM .... ${COLS}"

    # iterate over values
    for INDEX in $(seq 0 $((COLS - 1)));do
        echo -e "\tCOL[${INDEX}] = ${ROW[${INDEX}]}"
    done

    # increment line counter
    let LN=$((LN + 1))

done < ${TABLE}

# clean up
rm -rf ${TABLE}

# we are done
exit 0

<强>输出

daniel@synapse:/tmp$ ./arrays_2d.sh
-------------------------------------------------------------------
LINE NO# ....... 0
COLUMNS  ....... col1    col2    col3    col4
COLUMNS NUM .... 4
    COL[0] = col1
    COL[1] = col2
    COL[2] = col3
    COL[3] = col4
-------------------------------------------------------------------
LINE NO# ....... 1
COLUMNS  ....... [0,0]   [0,1]   [0,2]   [0,3]
COLUMNS NUM .... 4
    COL[0] = [0,0]
    COL[1] = [0,1]
    COL[2] = [0,2]
    COL[3] = [0,3]
-------------------------------------------------------------------
LINE NO# ....... 2
COLUMNS  ....... [1,0]   [1,1]   [1,2]   [1,3]
COLUMNS NUM .... 4
    COL[0] = [1,0]
    COL[1] = [1,1]
    COL[2] = [1,2]
    COL[3] = [1,3]

答案 1 :(得分:0)

我根本没有看到任何问题。

一些代码审核:

for  oline in ${ArrayObs[@]};do
缺少

引号:需要"${ArrayObs[@]}"

  valuesMO=`echo ${oline}`

valuesMO=$oline相同,但空格被挤压。这是你的意图吗?

  varDP=`echo ${oline} | awk '{print $6}'`
     if [ "${ArrayObs[0]}" == "$oline" ]; then
      echo -e " first time"
      awk '{printf ("%.3f\n", $6)}' valuesMO > MkDepth

你有一个名为valuesMO的文件吗?您错过了$

    else
      echo -e " not the first time"
      awk '{printf ("%.3f\n", $6)}' valuesMO >> MkDepth
    fi
  done

您不需要if声明。在for循环之后放置重定向以捕获其所有输出。像这样:

for x in ...; do
    echo $x
done > MkDepth