Read a file and save every word in a variable to use

Hello there

so i have a txt file containing word like "one two three four plus four five six".

I want to save every word in the file into a variable, and then use that variable to generate real numbers and apply the arithmetic value on them.

example: the txt files becomes 123 + 456 and give the result.

I got the idea to use this:

for word in $(<$file); do
                #echo "$word"
done
this only read every word. I tried to do:
case "$word" in
                   "zero") $word = "0"

and so on but it doesn't actually allow me to save each word in a different variable.

Thanks in advance

If you know the word count in the file, you can read into variables:

$ read V1 V2 V3 V4 V5 V6 V7 V8 < file
$ echo $V2
two

If you don't, read into an array. Careful: this syntax is different between shells.

$ read -a ARR < file2
$ echo ${ARR[1]}
two

For your further task, this thread and the references therein may give you valuable hints / directions.

1 Like

Hi azaiie...

This sounds easy, but is much more difficult than you think using a fully POSIX compliant shell.
This is fully POSIX compliant and gets 39 individual words into individual variables just as you wanted.
Arrays per-se do not exist in POSIX but this creates a pseudo-array.

With a random file of words these variables have to be searched and the value used as the new variable with a relevant integer assigned to it.
Lots of conditional tasks as well as variable searching.

The rest should be easy.

#!/bin/sh

# #!/usr/local/bin/dash
# Tested using dash as the shell.

# Generate a file containing required words.
echo 'one two
buckle my shoe
three four
knock at the door
five six
pick up sticks
seven eight
lay them straight
nine zero
a big fat hero
multiply add
and maybe to subtract
divide too
just to satisfy you' > /tmp/txt

# Convert basic text file to single word lines.
tr ' ' '\n' < /tmp/txt > /tmp/text

# *******************************************
# **** The main pseudo-array generator. *****
INDEX=1
while read -r ARRAY
do
    eval MY_ARRAY${INDEX}='${ARRAY}'
    INDEX=$(( INDEX+1 ))
done < /tmp/text
# You now have a number of variables containing
# 1 word in each. The above is POSIX compliant.
# *******************************************

# Check the environment to see if the variables are there.
set

And the results, viewing the environment variables.

Last login: Fri Apr 12 18:47:43 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./words1.sh
ARRAY=
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.OnpUkj5yS0/Render
BASH=/bin/sh
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=([0]="0")
BASH_SOURCE=([0]="./words1.sh")
BASH_VERSINFO=([0]="3" [1]="2" [2]="57" [3]="1" [4]="release" [5]="x86_64-apple-darwin18")
BASH_VERSION='3.2.57(1)-release'
DIRSTACK=()
EUID=502
GROUPS=()
HOME=/Users/amiga
HOSTNAME=Barrys-MBP
HOSTTYPE=x86_64
IFS='     
'
INDEX=40
LANG=en_GB.UTF-8
LOGNAME=amiga
MACHTYPE=x86_64-apple-darwin18
MY_ARRAY1=one
MY_ARRAY10=the
MY_ARRAY11=door
MY_ARRAY12=five
MY_ARRAY13=six
MY_ARRAY14=pick
MY_ARRAY15=up
MY_ARRAY16=sticks
MY_ARRAY17=seven
MY_ARRAY18=eight
MY_ARRAY19=lay
MY_ARRAY2=two
MY_ARRAY20=them
MY_ARRAY21=straight
MY_ARRAY22=nine
MY_ARRAY23=zero
MY_ARRAY24=a
MY_ARRAY25=big
MY_ARRAY26=fat
MY_ARRAY27=hero
MY_ARRAY28=multiply
MY_ARRAY29=add
MY_ARRAY3=buckle
MY_ARRAY30=and
MY_ARRAY31=maybe
MY_ARRAY32=to
MY_ARRAY33=subtract
MY_ARRAY34=divide
MY_ARRAY35=too
MY_ARRAY36=just
MY_ARRAY37=to
MY_ARRAY38=satisfy
MY_ARRAY39=you
MY_ARRAY4=my
MY_ARRAY5=shoe
MY_ARRAY6=three
MY_ARRAY7=four
MY_ARRAY8=knock
MY_ARRAY9=at
OPTERR=1
OPTIND=1
OSTYPE=darwin18
PATH=/Library/Frameworks/Python.framework/Versions/3.5/bin:/Users/amiga/Programs:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PIPESTATUS=([0]="1")
POSIXLY_CORRECT=y
PPID=1363
PS4='+ '
PWD=/Users/amiga/Desktop/Code/Shell
SHELL=/bin/bash
SHELLOPTS=braceexpand:hashall:interactive-comments:posix
SHLVL=2
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.a4cnRI4Q71/Listeners
TERM=xterm-256color
TERM_PROGRAM=Apple_Terminal
TERM_PROGRAM_VERSION=421.1
TERM_SESSION_ID=C5501462-11A6-4B33-AC5B-14C026610778
TMPDIR=/var/folders/9c/bb_c667j5nj5cbbkw__1l8n40000gp/T/
UID=502
USER=amiga
XPC_FLAGS=0x0
XPC_SERVICE_NAME=0
_=ARRAY
AMIGA:amiga~/Desktop/Code/Shell> _
1 Like

thanks alot, i thought about comparing every word with its number using case or if but then i was stuck in making that one two three a full integer 123, but with the array it works now, thanks alot wisecracker and rudic.

If you don't care about your commandline parameters, there's a very easy trick, which works in POSIX bourne, BASH, and even things like zsh.

set -- `cat file.txt`

$1 will become the first word, $2 the second, etc, etc.

With bash-4 it's a piece of cake:

#!/bin/bash
# bash-4 required
declare -A sym
sym=(
[zero]=0
[one]=1
[two]=2
[three]=3
[four]=4
[five]=5
[plus]=+
)

while read -r -a words
do
  out=""
  for word in "${words[@]}"
  do
    out+=${sym[$word]-" $word "}
  done
  echo "$out"
done
1 Like

I'm grateful for you brother, thanks alot for the quick response, this is much cleaner and easier to understand.

And how can i use exp to make a result out of the arithmetic equation ? If there is plus, minus and multiplication in the array as well ?

Extending MadeInGermany's appoach by sym[six]=6 and after running his code in bash 4 as required, try

echo $((out))
 1690

Or, try

echo $out | bc
1690
1 Like

it worked, thanks alot. How can i get better at this, like i didn't think of $((out)), i thought of using "if" and conditions to compare it with the input that i give which will make my code even more complicated. Any tips for that ?. Thanks alot brother

What can I say? Read, exercise, be open. This forum (amongst others) is great for learning. Look around, find all types of problems, scrutinize and understand the proposed solutions. Apply what you learned. Solve found problems on your own, and compare to what others proposed. man pages are your friends.