-1

I have a text file with a few basic words:

-banana
-mango
-sleep

When I run my script:

#!/bin/sh
WORD_FILE="testwoord.txt"
WORDS_ARRAY=cat $WORD_FILE

The output is like:

/home/username/bin/testword.txt: 1 /home/username/bin/restword.txt: banana: not found
/home/username/bin/testword.txt: 1 /home/username/bin/restword.txt: mango: not found
/home/username/bin/testword.txt: 1 /home/username/bin/restword.txt: sleep: not found

Why is it doing this? What I actually want is a script that reads words from a .txt file and puts it in an array.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Mirwais
  • 1
  • 1
  • 6
  • Thank you for your reply! I did that and it gave me this: cat: testword.txt: No such file er directory – Mirwais Mar 30 '15 at 15:40
  • Is testword.txt in your current directory? Is $WORD_FILE set to just `testword.txt` or the complete pathname `/home/username/bin/restword.txt`? What do you get if you type `cat $WORD_FILE`? – rojomoke Mar 30 '15 at 15:50
  • 1
    Your file is called "testwoord" not "testword". – hemflit Mar 30 '15 at 15:53
  • If I delete `WORDS_ARRAY=cat $WORD_FILE` and replace it with `cat $WORD_FILE` it also says no such file or directory. But when I type WORDS_ARRAY=cat $WORD_FILE (without `) it gives me the words but with not found after it – Mirwais Mar 30 '15 at 15:56
  • And yes, they are in the same folder (bin) – Mirwais Mar 30 '15 at 15:57
  • @Mirwais, running an executable doesn't automatically change directories to that executable's location. This is why running `ls` shows you your current directory, not the directory where `ls` is located. Thus, unless you're actually in `/home/username/bin` when running this script, it won't be able to find those files without additional work. – Charles Duffy Mar 30 '15 at 16:05
  • @Mirwais, ...if you want to find your script's location, see BashFAQ #28: http://mywiki.wooledge.org/BashFAQ/028 – Charles Duffy Mar 30 '15 at 16:06
  • @CharlesDuffy OK, I will look into it – Mirwais Mar 30 '15 at 16:15

2 Answers2

4

To explain why this doesn't work:

WORDS_ARRAY=cat $WORD_FILE

runs the command generated by expanding, string-splitting, and glob-expanding $WORD_FILE with the variable WORDS_ARRAY exported in the environment with the value cat.


Instead, consider:

#!/bin/bash
#      ^^ -- important that this is bash, not sh: POSIX sh doesn't have arrays!

WORD_FILE=testword.txt
readarray -t WORDS_ARRAY <"$WORD_FILE"
printf 'Read a word: %q\n' "${WORDS_ARRAY[@]}"

...which will create an actual array, not a string variable containing whitespace (as WORDS_ARRAY=$(cat $WORD_FILE) would).


By the way, using all-upper-case variable names is bad form here. To quote the POSIX spec:

Environment variable names used by the utilities in the Shell and Utilities volume of POSIX.1-2008 consist solely of uppercase letters, digits, and the ( '_' ) from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names. Uppercase and lowercase letters shall retain their unique identities and shall not be folded together. The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • I will use lower-case variable from now on! I tried what you explained but it gave me: `Syntax error: redirection unexpected` – Mirwais Mar 30 '15 at 16:05
  • @Mirwais, is your shell actually bash? That's an error you'd typically get if your shell were `/bin/sh`. Be sure you run `bash yourscript`, not `sh yourscript`, and that the script starts with `#!/bin/bash`, not `#!/bin/sh`, if you want its shell to be bash (as I assume to be true, since you tagged this question [tag:bash]). – Charles Duffy Mar 30 '15 at 16:07
  • Ah.. I feel so stupid.. Thank you! Now it runs and says: testwoord.txt: No such file or directory Read a word: '' – Mirwais Mar 30 '15 at 16:12
  • Is there really a `testwoord.txt` is your current directory (the directory you're in when you run the script, not the directory the script is located in)? I commented on your original question to a link to a FAQ entry describing how to get the latter one, if you need it. – Charles Duffy Mar 30 '15 at 16:13
  • 1
    To complement the explanation of why the OP's command didn't work: you cannot just place a bare command (`cat $WORD_FILE`) on the right side of a variable assignment and expect it to be executed - a command substitution (`$(...)`) is needed (leaving aside the aspect that this won't create an _array_). – mklement0 Mar 30 '15 at 18:29
1

To complement Charles Duffy's helpful answer:

Note that the variable names were changed to lowercase, as per Charles' recommendation.

Here a bash 3.x (and above) version of the command for reading lines into a bash array (readarray requires bash 4.x):

IFS=$'\n' read -d '' -ra words_array < "$word_file"

If you want to store individual words (across lines), use:

read -d '' -ra words_array < "$word_file"

To print the resulting array:

for ((i=0; i<"${#words_array[@]}"; i++)); do echo "word #$i: "${words_array[i]}""; done
Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775