Greg
Greg

Reputation: 2271

Manually iterating a line of a file | bash

I could do this in any other language, but with Bash I've looked far and wide and could not find the answer.

I need to manually increase $line in a script. Example:

for line in `cat file`
do
foo()
       foo_loop(condition)
{
 do_something_to_line($line) 
}
done

If you notice, every time the foo_loop iterates, $line stays the same. I need to iterate $line there, and make sure the original for loop only runs the number of lines in file.

I have thought about finding the number of lines in file using a different loop and iterating the line variable inside the inner loop of foo().

Any ideas?

EDIT:

Sorry for being so vague.

Here we go:

I'm trying to make a section of my code execute multiple times (parallel execution)

Function foo() # Does something
for line in `cat $temp_file`;
foo($line)

That code works just fine, because foo is just taking in the value of line; but if I wanted to do this:

Function foo() # Does something
for line in `cat $temp_file`;
while (some condition)
foo($line)
end

$line will equal the same value throughout the while loop. I need it to change with the while loop, then continue when it goes back to the for. Example:

line = Hi
foo{ echo "$line" }; 
for line in `cat file`;
while ( number_of_processes_running -lt max_number_allowed)
foo($line)
end

If the contents of file were

Hi \n Bye \n Yellow \n Green \n

The output of the example program would be (if max number allowed was 3)

Hi Hi Hi Bye Bye Bye Yellow Yellow Yellow Green Green Green.

Where I want it to be

Hi Bye Yellow Green 

I hope this is better. I'm doing my best to explain my problem.

Upvotes: 8

Views: 10215

Answers (3)

Dennis Williamson
Dennis Williamson

Reputation: 360065

You should post follow-ups as edits to your question or in comments rather than as an answer.

This structure:

while read line
do
    for (( i=1; i<$max_number_allowed; i++ ))
    do
        foo $line
    done
done < file

Yields:

Hi
Hi
Hi
Bye
Bye
Bye
...etc.

While this one:

for (( i=1; i<$max_number_allowed; i++ ))
do
    while read line
    do
        foo $line
    done < file
done

Yields:

Hi
Bye
Yellow
Green
Hi
Bye
Yellow
Green
...etc.

Upvotes: 1

Steven
Steven

Reputation: 13769

Long story short, while read line; do _____ ; done

Then, make sure you have double-quotes around "$line" so that a parameter isn't delimited by spaces.

Example:

$ cat /proc/cpuinfo | md5sum
c2eb5696e59948852f66a82993016e5a *-

$ cat /proc/cpuinfo | while read line; do echo "$line"; done | md5sum
c2eb5696e59948852f66a82993016e5a *-

Second example # add .gz to every file in the current directory: # If any files had spaces, the mv command for that line would return an error.

$ find -type f -maxdepth 1 | while read line; do mv "$line" "$line.gz"; done

Upvotes: 6

Buggabill
Buggabill

Reputation: 13901

Instead of using a for loop to read through the file you should maybe read through the file like so.

#!bin/bash

while read line
do
    do_something_to_line($line)
done < "your.file"

Upvotes: 16

Related Questions