I have one file with a list of names. I need to loop through all names in this file from an external file with a shell script. How can I do that?
Example files:
scripts/names.txt
alison barb charlie david
scripts/script.sh
NAMES="" #names from names.txt file for NAME in $NAMES; do echo "$NAME" done
How can I explode the names.txt file into an array in a separate shell script?
Simply setting the IFS variable to a new line works for the output of a command but not when processing a variable that contains new lines. As you can see, echoing the variable or iterating over the cat command prints each of the lines one by one correctly.
Execute the following command to insert the file's name, followed by a newline, followed by the text Loops Rule! into each file: for FILE in *; do echo -e "$FILE\nLoops Rule\!" > $FILE; done.
Because text files are sequences of lines of text, we can use the for loop to iterate through each line of the file. A line of a file is defined to be a sequence of characters up to and including a special character called the newline character.
One way would be:
while read NAME do echo "$NAME" done < names.txt
EDIT: Note that the loop gets executed in a sub-shell, so any modified variables will be local, except if you declare them with declare
outside the loop.
Dennis Williamson is right. Sorry, must have used piped constructs too often and got confused.
You'll be wanting to use the 'read' command
while read name do echo "$name" done < names.txt
Note that "$name" is quoted -- if it's not, it will be split using the characters in $IFS
as delimiters. This probably won't be noticed if you're just echoing the variable, but if your file contains a list of file names which you want to copy, those will get broken down by $IFS
if the variable is unquoted, which is not what you want or expect.
If you want to use Mike Clark's approach (loading into a variable rather than using read), you can do it without the use of cat
:
NAMES="$(< scripts/names.txt)" #names from names.txt file for NAME in $NAMES; do echo "$NAME" done
The problem with this is that it loads the whole file into $NAMES
, when you read it back out, you can either get the whole file (if quoted) or the file broken down by $IFS
, if not quoted. By default, this will give you individual words, not individual lines. So if the name "Mary Jane" appeared on a line, you would get "Mary" and "Jane" as two separate names. Using read
will get around this... although you could also change the value of $IFS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With