【问题标题】:Bash reading txt file and storing in arrayBash读取txt文件并存储在数组中
【发布时间】:2013-03-24 07:14:54
【问题描述】:

我正在编写我的第一个 Bash 脚本,我对 C 和 C# 有一定的经验,所以我认为程序的逻辑是正确的,只是语法太复杂了,因为显然有很多不同的方法可以编写相同的东西!

这是脚本,它只是检查参数(字符串)是否包含在某个文件中。如果是这样,它将文件的每一行存储在一个数组中,并将该数组的一项写入文件中。我确信必须有更简单的方法来实现这一点,但我想用 bash 循环做一些练习

#!/bin/bash

NOME=$1
c=0

#IF NAME IS FOUND IN THE PHONEBOOK THEN STORE EACH LINE OF THE FILE INTO ARRAY
#ONCE THE ARRAY IS DONE GET THE INDEX OF MATCHING NAME AND RETURN ARRAY[INDEX+1]

if grep "$NOME" /root/phonebook.txt ; then
        echo "CREATING ARRAY"
        while read line
        do
                myArray[$c]=$line # store line
                c=$(expr $c + 1) # increase counter by 1
        done < /root/phonebook.txt

else
        echo "Name not found"
fi

c=0
for i in myArray;
        do
              if   myArray[$i]="$NOME" ;  then
                 echo ${myArray[i+1]} >> /root/numbertocall.txt
              fi

done

这段代码只返回myArray的第二项(myArray[2])或者文件的第二行,为什么?

【问题讨论】:

  • 你为什么要使用 grep -q?
  • 哎呀这不是故意的......谢谢
  • 在您的问题中找不到问题
  • 您是否以 root 身份运行?在以 root 身份登录时学习编写 shell 脚本有点像在一级方程式赛车中学习驾驶汽车。它很快,但很危险。除非绝对必须,否则不要以 root 身份运行。然后非常非常小心。
  • 谢谢!没想到

标签: linux bash loops if-statement


【解决方案1】:

第一部分(构建数组的地方)看起来不错,但第二部分有几个严重的错误:

  • for i in myArray; -- 这将执行一次循环,$i 设置为“myArray”。在这种情况下,您希望 $i 遍历 myArray 的索引,因此您需要使用

    for i in "${!myArray[@]}"
    

    for ((i=0; i<${#a[@]}; i++))
    

    (虽然我通常更喜欢第一个,因为它适用于非连续和关联数组)。

    另外,除非do 在同一行,否则您不需要;(在shell 中,; 主要相当于换行符,因此在行尾使用分号是多余的) .

  • if myArray[$i]="$NOME" ; then -- if 语句接受一个命令,因此会将myArray[$i]="$NOME" 视为一个赋值命令,这根本不是您想要的。为了比较字符串,您可以使用test 命令或其同义词[

    if [ "${myArray[i]}" = "$NOME" ]; then
    

    或 bash 条件表达式

    if [[ "${myArray[i]}" = "$NOME" ]]; then
    

    两者非常相似,但条件表达式的语法更简洁(例如,在测试命令中,&gt; 重定向输出,而\&gt; 是字符串比较;在[[ ]] 中,普通的&gt; 是比较)。

    在任何一种情况下,您都需要为 myArray 使用适当的 $ 表达式,否则它将被解释为文字。另一方面,您不需要在 "${myArray[i]}" 中的 i 之前需要一个 $,因为它位于数字表达式上下文中,因此会自动扩展。

    最后,请注意,元素之间的空格是绝对需要的——在 shell 中,空格是非常重要的分隔符,而不仅仅是为了便于阅读,就像它们通常在 c 中那样。

【讨论】:

    【解决方案2】:

    1.-这是你写的小调整

    #!/bin/bash
    
    NOME=$1
    
    #IF NAME IS FOUND IN THE PHONE-BOOK **THEN** READ THE PHONE BOOK LINES INTO AN ARRAY VARIABLE
    #ONCE THE ARRAY IS COMPLETED, GET THE INDEX OF MATCHING LINE AND RETURN ARRAY[INDEX+1]
    
    c=0
    if grep "$NOME" /root/phonebook.txt ; then
    
           echo "CREATING ARRAY...."
           IFS= while read -r line    #IFS= in case you want to preserve leading and trailing spaces
           do
                 myArray[c]=$line     # put line in the array
                 c=$((c+1))           # increase counter by 1
           done < /root/phonebook.txt
    
    
           for i in ${!myArray[@]}; do
                 if  myArray[i]="$NOME" ;  then
                     echo ${myArray[i+1]} >> /root/numbertocall.txt
                 fi
           done
    
    
    else
           echo "Name not found"
    fi
    

    2.-但你也可以像这样读取数组并停止循环:

    #!/bin/bash
    
    NOME=$1
    
    c=0
    if grep "$NOME" /root/phonebook.txt ; then
    
           echo "CREATING ARRAY...."
           readarray myArray < /root/phonebook.txt
    
    
           for i in ${!myArray[@]}; do
                 if  myArray[i]="$NOME" ;  then
                     echo ${myArray[i+1]} >> /root/numbertocall.txt
                     break            # stop looping
                 fi
           done
    
    
    else
           echo "Name not found"
    fi
    exit 0
    

    3.- 以下改进了一些事情。假设 a)$NAME 与包含它的整行匹配,并且 b) 在找到 $NOME 之后总是有一行,这将起作用;如果不是(如果 $NOME 可以是电话簿中的最后一行),那么您需要进行一些小调整。

    !/bin/bash
    PHONEBOOK="/root/phonebook.txt"
    NUMBERTOCALL="/root/numbertocall.txt"
    NOME="$1"
    myline=""
    
    myline=$(grep -A1 "$NOME" "$PHONEBOOK" | sed '1d')
    
    if [ -z "$myline" ]; then 
          echo "Name not found :-("
    
    else
          echo -n "$NOME FOUND.... "
          echo "$myline" >> "$NUMBERTOCALL"
          echo  " .... AND SAVED! :-)"
    
    fi
    exit 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 2018-05-03
      • 2020-05-25
      • 2022-01-05
      • 2015-07-23
      • 2021-01-18
      相关资源
      最近更新 更多