4

I'm writing my first BASH script , I have some experience with c and c# so I think the logic of the program is correct..it's just the syntax is so complicated because apparently there are billions of ways to write the same thing!

Anyway here is the script: it simply checks if the argument (string) is contained in a certain file . If so it stores each line of the file in an array and writes an item of the array in a file. I'm sure there must be easier ways to achieve that but I want to do some practice with bash loops

    #!/bin/bash

NOME=$1
c=0


#IF NAME IS FOUND IN THE PHONEBOOK THANK 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

This code does returns the only the second item of myArray (myArray[2] or the second line of the file)..why?

  • What relevance has the \t? Both the text and the rest of the code just refer to lines. – Hauke Laging Apr 2 '13 at 21:26
  • Not a direct answer, so it's just a comment, but I'd do this with one a one liner grep; grep -P -o "(?<=$NOME\t).+" – Patrick Apr 2 '13 at 21:34
  • @Patrick Classic X-Y problem, so I think your comment should be an answer. It does the right thing after all. – l0b0 Apr 3 '13 at 8:50
7
IFS=$'\n' a=($(cat phonebook.txt))
for i in $(seq ${#a[*]}); do
    [[ ${a[$i-1]} = $name ]] && echo "${a[$i]}"
done

In Bash 4 IFS=$'\n' a=($(cat phonebook.txt)) can be replaced with mapfile -t a < phonebook.txt.

grep -A1 prints one line after the match. -x disables regex like -F but it only matches complete lines.

grep -x "$name" -A1 phonebook.txt | tail -n1
  • You may want to validate the contents of the file first. Up to you. – Wildcard Apr 20 '17 at 3:33
2
index=0
while read line; do
  myArray[index]="$line"
done < inputfile

Newer versions of bash support associative arrays. That would make it easier:

declare -A myArray
while read name; do
  read number
  myArray[name]="$number"
done < inputfile

echo ${myArray[name]}
  • and how would you return the item of myArray[name + 1] ? – Aaron Ullal Apr 2 '13 at 21:43
  • In the indexed example you already had the solution thus I didn't copy it. – Hauke Laging Apr 2 '13 at 22:36
  • May I be wrong, but using such pipe would not make myArray "invisible" to outside of loop??? – Frederic Yesid Peña Sánchez Jan 19 '15 at 22:27
  • @FredericYesidPeñaSánchez Neither the question nor my answer contains a pipeline thus I don't know what you are talking about. – Hauke Laging Jan 19 '15 at 23:26
  • "while read name;" looks to me like a pipeline, anyway, i found the "declare -a array" fixes troubles i got before, thanks!!! +1 – Frederic Yesid Peña Sánchez Jan 19 '15 at 23:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.