I\'ve read this question about how to read n characters from a text file using bash. I would like to know how to read a word at a time from a file that looks like:
Ordinarily, you should read from a file using a while read -r line
loop. To do this and parse the words on the lines requires nesting a for
loop inside the while
loop.
Here is a technique that works without requiring nested loops:
for word in $(<inputfile)
do
echo "$word"
done
In the context given, where the number of words is known:
while read -r word1 word2 _; do
echo "Read a line with word1 of $word1 and word2 of $word2"
done
If you want to read each line into an array, read -a
will put the first word into element 0 of your array, the second into element 1, etc:
while read -r -a words; do
echo "First word is ${words[0]}; second word is ${words[1]}"
declare -p words # print the whole array
done
This can be done using AWK too:
awk '{for(i=1;i<=NF;i++) {print $i}}' text_file
The way to do this with standard input is by passing the -a
flag to read:
read -a words
echo "${words[@]}"
This will read your entire line into an indexed array variable, in this case named words. You can then perform any array operations you like on words with shell parameter expansions.
For file-oriented operations, current versions of Bash also support the mapfile built-in. For example:
mapfile < /etc/passwd
echo ${MAPFILE[0]}
Either way, arrays are the way to go. It's worth your time to familiarize yourself with Bash array syntax to make the most of this feature.
The read
command by default reads whole lines. So the solution is probably to read the whole line and then split it on whitespace with e.g. for
:
#!/bin/sh
while read line; do
for word in $line; do
echo "word = '$word'"
done
done <"myfile.txt"
In bash, just use space as delimiter (read -d ' '
). This method requires some preprocessing to translate newlines into spaces (using tr
) and to merge several spaces into a single one (using sed
):
{
tr '\n' ' ' | sed 's/ */ /g' | while read -d ' ' WORD
do
echo -n "<${WORD}> "
done
echo
} << EOF
Here you have some words, including * wildcards
that don't get expanded,
multiple spaces between words,
and lines with spaces at the begining.
EOF
The main advantage of this method is that you don't need to worry about the array syntax and just work as with a for
loop, but without wildcard expansion.