Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I iterate through lines in an external file with shell? [duplicate]

Tags:

bash

shell

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?

like image 534
Ryan Avatar asked Jul 05 '12 17:07

Ryan


People also ask

How do I loop through a line in bash?

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.

How do I loop over a file?

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.

Which file function can be used to loop on a file line by line?

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.


2 Answers

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.

like image 81
smocking Avatar answered Sep 24 '22 21:09

smocking


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

like image 28
Barton Chittenden Avatar answered Sep 21 '22 21:09

Barton Chittenden