Reputation: 1272
I have a bash script which asks for two arguments with a space between them. Now I would like to automate filling out the prompt in the command line with reading from a text file. The text file contains a list with the argument combinations.
So something like this in the command line I think;
for line in 'cat text.file' ; do script.sh ; done
Can this be done? What am I missing/doing wrong?
Thanks for the help.
Upvotes: 0
Views: 2114
Reputation: 19315
'cat text.file'
is a string literal, $(cat text.file)
would expand to output of command however cat
is useless because bash can read file using redirection, also with quotes it will be treated as a single argument and without it will split at space tab and newlines.
Bash syntax to read a file line by line, but will be slow for big files
while IFS= read -r line; do ... "$line"; done < text.file
-r
option preserves \
another way, to read whole file is content=$(<file)
, note the <
inside the command substitution. so a creative way to read a file to array, each element a non-empty line:
read_to_array () {
local oldsetf=${-//[^f]} oldifs=$IFS
set -f
IFS=$'\n' array_content=($(<"$1")) IFS=$oldifs
[[ $oldsetf ]]||set +f
}
read_to_array "file"
for element in "${array_content[@]}"; do ...; done
oldsetf
used to store current set -f
or set +f
settingoldifs
used to store current IFS
IFS=$'\n'
to split on newlines (multiple newlines will be treated as one)set -f
avoid glob expansion for example in case line contains single *
()
around $()
to store the result of splitting to an arrayUpvotes: 1
Reputation: 21965
A while
loop is probably what you need. Put the space separated strings in the file text.file
:
cat text.file
bingo yankee
bravo delta
Then write the script in question like below.
#!/bin/bash
while read -r arg1 arg2
do
/path/to/your/script.sh "$arg1" "$arg2"
done<text.file
Upvotes: 4
Reputation: 1220
If I were to create a solution determined by the literal of what you ask for (using a for loop and parsing lines from a file) I would use iterations determined by the number of lines in the file (if it isn't too large).
Assuming each line has two strings separated by a single space (to be used as positional parameters in your script:
file="$1"
f_count="$(wc -l < $file)"
for line in $(seq 1 $f_count)
do
script.sh $(head -n $line $file | tail -n1) && wait
done
You may have a much better time using sjsam's solution however.
Upvotes: 0
Reputation: 7303
Don't use for
to read files line by line
Try something like this:
#!/bin/bash
ARGS=
while IFS= read -r line; do
ARGS="${ARGS} ${line}"
done < ./text.file
script.sh "$ARGS"
This would add each line to a variable which then is used as the arguments of your script.
Upvotes: 1