Bash script does not continue to read the next line of file

Asked
Active3 hr before
Viewed126 times

9 Answers

90%

You can see each line is an ffmpeg command. However, the script just executes the first line. Just a minute ago it was doing nearly all of the commands. It was missing half for some reason. I edited the text file that contained the commands and now it will only do the first line. Here is my bash script:,2) Since now the skript will not wait till completion of the ffmpeg process, we have to prevent our script from starting several ffmpeg processes. We achieve this goal by delaying the loop pass while there is at least one running ffmpeg process.,I have a shell script that saves the output of a command that is executed to a CSV file. It reads the command it has to execute from a shell script which is in this format:,Unless you are planning to read something from standard input after the loop, you don't need to preserve and restore the original standard input (though it is good to see you know how).

I think that should do the same and seems to be correct:

#!/bin/bash

CSVFILE = /tmp/file.csv

cat "$@" |
   while read line;
do
   echo "Executing '$line'"
START = $(date + % s)
eval $line & > /dev/null
END = $(date + % s)
let DIFF = $END - $START

echo "$line, $START, $END, $DIFF" >> "$CSVFILE"
echo "It took ${DIFF}s"
done
load more v
88%

If you have a potentially malformed input file that may be missing its last line, you could add a newline to it, just to be sure.,The read builtin is only meant to read text files. You aren't passing a text file, so you can't hope it to work seamlessly. The shell reads all the lines — what it's skipping are the extra characters after the last line.,If the last line doesn't end with a newline character, that line won't be read. I was wondering why? ,To read all the lines, regardless if they are ended with a new line or not:

You'd do:

while IFS = read - r url || [-n "$url"];
do
   printf '%s\n'
"$url"
done < url.list
load more v
72%

for i in `seq 1 $numLines`;
do
   line = $(sed - n '{$i}p'
      outputFile)
echo $line
done
load more v
65%

The syntax is as follows for bash, ksh, zsh, and all other shells to read a file line by line,princess anu, there’s no need to use arithmetic; just read the file in groups of three lines:,can anyone help me to include the line number while read line by line ,,This page explained how to read file line by line in bash shell script.

#!/bin/bash

input = "/path/to/txt/file"
while IFS = read - r line
do
   echo "$line"
done < "$input"
load more v
75%

Now from the output, you can see empty lines are ignored.,We can redirect the content of the file to while loop using the Input redirection operator (<).,cat /etc/passwd will read the contents of the file and pass it as input through the pipe.,You can also store the file name to a variable and pass it through a redirection operator.

Before seeing how to read file contents using while loop, a quick primer on how while loop works. While loop evaluates a condition and iterates over a given set of codes when the condition is true.

while [CONDITION]
do
   code block
done
load more v
40%

When using a variable one needs to put a $ sign in front of it: print $state $price.,Check my AWK programming introduction bye clicking on this sentence!,Check my PERL programming introduction bye clicking on this sentence!,So one can question a string in a variable like: if [[ $var = fo@(?4*67).c ]];then ...

A script has four types of lines: The shell defining line at the top, empty lines, commentary lines starting with a # and command lines. See the following top of a script as an example for these types of lines:

#!/usr/bin/ksh

# Commentary......

   file = /path/file
if [
   [$file = $1]
];
then
command
fi

A command starts with the first word on a line or if it's the second command on a line with the first word after a";'.
A command ends either at the end of the line or whith a ";". So one can put several commands onto one line:

print - n "Name: ";
read name;
print ""


One can continue commands over more than one line with a "\" immediately followed by a newline sign which is made be the return key:

grep filename | sort - u | awk '{print $4}' | \
   uniq - c >> /longpath/file

if then fi

if [
   [$value - eq 7]
];
then
print "$value is 7"
fi
or:

   if [
      [$value - eq 7]
   ]
then
print "$value is 7"
fi
or:

   if [
      [$value - eq 7]
   ];
then print "$value is 7";
fi

if then else fi

if [
   [$name = "John"]
];
then
print "Your welcome, ${name}."
else
   print "Good bye, ${name}!"
fi

if then elif then else fi

if [
   [$name = "John"]
];
then
print "Your welcome, ${name}."
elif[[$name = "Hanna"]];
then
print "Hello, ${name}, who are you?"
else
   print "Good bye, ${name}!"
fi

case esac

case $var in
   john | fred) print $invitation;;
martin) print $declination;;
*) print "Wrong name...";;
esac

while do done

while [
   [$count - gt 0]
];
do
   print "\$count is $count"
   ((count -= 1))
done

until do done

until[[$answer = "yes"]];
do
   print - n "Please enter \"yes\": "
read answer
print ""
done

for var in list do done

for foo in $(ls);
do
   if [
      [-d $foo]
   ];
then
print "$foo is a directory"
else
   print "$foo is not a directory"
fi
done

One can skip the rest of a loop and directly go to the next iteration with: "continue".

while read line
do
   if [
      [$line = * .gz]
   ];
then
continue
else
   print $line
fi
done

One can also prematurely leave a loop with: "break".

while read line;
do
   if [
      [$line = * !(.c)]
   ];
then
break
else
   print $line
fi
done

The number of command line arguments is stored in $# so one can check
for arguments with:

if [
   [$ # - eq 0]
];
then
print "No Arguments"
exit
fi

The single Arguments are stored in $1, ....$n and all are in $* as one string. The arguments cannot
directly be modified but one can reset the hole commandline for another part of the program.
If we need a first argument $first for the rest of the program we do:

if [
   [$1 != $first]
];
then
set $first $ *
   fi

One can iterate over the command line arguments with the help of the shift command. Shift indirectly removes the first argument.

until[[$ # - qe 0]];
do
   # commands....
shift
done

One can also iterate with the for loop, the default with for is $*:

for arg;
do
   print $arg
done

To compare strings one uses "=" for equal and "!=" for not equal.
To compare numbers one uses "-eq" for equal "-ne" for not equal as well as "-gt" for greater than
and "-lt" for less than.

if [
   [$name = "John"]
];
then
# commands....
fi
if [
   [$size - eq 1000]
];
then
# commands....
fi

With "&&" for "AND" and "||" for "OR" one can combine statements:

if [
   [$price - lt 1000 || $name = "Hanna"]
];
then
# commands....
fi
if [
   [$name = "Fred" && $city = "Denver"]
];
then
# commands....
fi

One can make one in either of the following two ways:

function foo {
   # commands...
}

foo() {
   # commands...
}

To get each line of a file into a variable iteratively do:

{
   while read myline;
   do
      # process $myline
   done
} < filename

To catch the output of a pipeline each line at a time in a variable use:

last | sort | {
   while read myline;do
      # commands
   done
}
load more v
22%

0
60%

That works well enough, up to a point. Suppose we have another text file that contains the names of the months. In this file, the escape sequence for a newline character has been appended to each line. We’ll call it “data2.txt.”,In Bash, you can use a while loop on the command line to read each line of text from a file and do something with it. Our text file is called “data.txt.” It holds a list of the months of the year.,The lines are read from the file and passed one by one to the process_line() function. All the lines are displayed correctly, including the odd one with the backspace, quotation marks, and multiple words in it.,It’s pretty easy to read the contents of a Linux text file line by line in a shell script—as long as you deal with some subtle gotchas. Here’s how to do it the safe way.

In Bash, you can use a while loop on the command line to read each line of text from a file and do something with it. Our text file is called “data.txt.” It holds a list of the months of the year.

January
February
March
   .
   .
October
November
December

Our simple one-liner is:

while read line;
do echo $line;
done < data.txt

That works well enough, up to a point. Suppose we have another text file that contains the names of the months. In this file, the escape sequence for a newline character has been appended to each line. We’ll call it “data2.txt.”

January\ n
February\ n
March\ n
   .
   .
October\ n
November\ n
December\ n

Let’s use our one-liner on our new file.

while read line;
do echo $line;
done < data2.txt

Here’s our script. It’s called “script1.sh.”

#!/bin/bash

Counter = 0

while IFS = ''
read - r LinefromFile || [
   [-n "${LinefromFile}"]
];
do

   ((Counter++))
echo "Accessing line $Counter: ${LinefromFile}"

done < "$1"

Copy and paste the script into an editor and save it with the filename “script1.sh.” Use the chmod command to make it executable.

chmod + x script1.sh

Let’s see what our script makes of the data2.txt text file and the backslashes contained within it.

. / script1.sh data2.txt
#!/bin/bash

Counter = 0

function process_line() {

   echo "Processing line $Counter: $1"

}

while IFS = ''
read - r LinefromFile || [
   [-n "${LinefromFile}"]
];
do

   ((Counter++))
process_line "$LinefromFile"

done < "$1"

Copy or type the script above into an editor and save it with the filename “script2.sh.” Make it executable with chmod :

chmod + x script2.sh

Now we can run it and pass in a new data file, “data3.txt.” This has a list of the months in it, and one line with many words on it.

January
February
March
   .
   .
October
November\ nMore text "at the end of the line"
December

Our command is:

. / script2.sh data3.txt
load more v
48%

similar but opposite to the t command: branch only if there has been no successful substitutions since the last input line was read. ,Branch to label only if there have been no successful substitutions since the last input line was read or conditional branch was taken. The label may be omitted, in which case the next cycle is started. ,(test) Branch to label only if there have been no successful substitutions since the last input line was read or conditional branch was taken. The label may be omitted, in which case the next cycle is started. ,The following commands demonstrate the step address usage:

sed SCRIPT INPUTFILE...
load more v

Other "undefined-undefined" queries related to "Bash script does not continue to read the next line of file"