7

I have this bash script:

for opt in string1 string2 string3 ... string99
do somestuff

It works, but I would like to replace the explicit listing of my strings with a file which actually contains all the strings; something like this:

strings=loadFromFile
for opt in $strings
do somestuff

How should I do this?

5 Answers5

11

while read VAR is probably best here, as it handles per-line input. You can redirect it from a file, e.g.:

while IFS= read -r THELINE; do
  echo "..$THELINE"
done </path/to/file

That'll give you each line prepended with ".."

For your example case:

while IFS= read -r opt; do
  #somestuff $opt
done </path/to/file

See Why is `while IFS= read` used so often, instead of `IFS=; while read..`? for explanations.

IBBoard
  • 298
8
while IFS= read -r opt
do 
    some_stuff
done < file_with_string

See Why is `while IFS= read` used so often, instead of `IFS=; while read..`? for explanations.

rush
  • 27,403
4

The while IFS= read -r line; do ...; done < aFile is the best answer

If your strings do not contain whitespace or \[*?, you could do

for word in $(< aFile); do something; done

$(< file) is a bash feature that reads the file (like cat except without having to spawn a new process).

glenn jackman
  • 85,964
2

Why don't you use the readarray builtin (requires bash >= 4.0)?

readarray < FileNameFromWhereToLoad    # push every line of 
                                       # 'FileNameFromWhereToLoad' onto 
                                       # $MAPFILE by default

for i in $MAPFILE ; do
    echo $i
done
user1146332
  • 2,234
  • This also requires newer version of bash. – Didi Kohen Sep 19 '12 at 14:12
  • i wouldn't call bash >= 4 new (release date was February 2009)! – user1146332 Sep 19 '12 at 14:31
  • 2
    Since he's using 2.05a, it is newer than what the asker has. In addition, some companies have avoided GPLv3 versions of bash, so do not have it in their system. – Didi Kohen Sep 19 '12 at 14:36
  • Do you have a crystal ball around? But yes, i agree with you about your last statement, i will add the version requirement of readarray to my answer. – user1146332 Sep 19 '12 at 14:39
  • Yes, I have a crystal ball which reflects the comment the poster wrote an hour ago on @h-dirk-schmitt answer. – Didi Kohen Sep 19 '12 at 14:45
  • 2
    I didn't read that. Thanks for the hint ;) Maybe my answer is of value for somebody who will search for an answer for a similar question!? – user1146332 Sep 19 '12 at 14:56
1

My advice:

cat INPUTFILE| {
  declare -a LINES
  mapfile -t LINES
  for line in "${LINES[@]}"
  do
    somestuff
  done
}