Bash Script Does Not Continue to Read The Next Line of File

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

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

no?

How to tell bash that the line continues on the next line

The character is a backslash \

From the bash manual:

The backslash character ‘\’ may be used to remove any special meaning
for the next character read and for line continuation.

Cannot read lines from a file using bash read command

RTF means Rich Text Format. It is a language for text formatting, developed and used mostly by Microsoft and deprecated for a while.

The text inside the file looks as you can see in the output of your code. It contains the words "Hello" and "World" but also formatting instructions.

Save the file as plain text, not RTF and it will contain only the text you typed in it.

test= in front of read does not have any effect in this context. You can remove it.

Make sure the last line of the file ends with a new-line character. read returns an non-zero exit status (and this means false) when it reaches the end of file and your code exits the while loop and does not display the last value read by read. If the file ends with a new-line character, the last line (that is read but not listed by the code) is empty, therefore nothing is lost.

It is a recommended practice for text files to always end with a newline character.


Alternatively you can print the value of line again after the loop. It contains the last line of the file (from the last end-of-line character until the end of file).

script not reading last line of a file

Use

grep . "${FILE_NAME}" | while read LINE

or

while read LINE
do
....
done < <(grep . "${FILE_NAME}")

The grep is less sensible to line-ending, and you will get empty-line skip for a free... :)

Honestly, never tried windows, all above is OK for unix...

EDIT Explanation:

make the next file:

echo -n -e 'line\n\nanother\nno line ending here>' >file.txt

the file contains 4 lines (although the last "line" is not a "correct" one)

line

another
no line ending here>

Usual shell routines, as read or wc looking for line ending. Therefore,

$ wc -l file.txt 
3 file.txt

When you grepping for '' (empty string) the grep returns every line where found the string, so

$ grep '' file.txt

prints

line

another
no line ending here>

When grep prints out the found lines - ensures than one `\n' exists at the end, so

$ grep '' file.txt | wc -l

returns

4

therefore, for these situations, is better to use grep with -c (count) and not wc.

$ grep -c '' file.txt
4

Now, the . dot. The dot mean any character. So, when you grepping for a ., you get all lines what contain at least one character. And therefore, it will skip all lines what doesn't contain any character = skips empty lines. So,

$ grep . file.txt
line
another
no line ending here>

again, with added line ending to the last line (and skipped the empty line). Remember, the (space) is character too, so when the line contains only one space it is NOT EMPTY. Counting non-empty lines

$ grep . file.txt | wc -l
3

or faster

$ grep -c . file.txt
3

Shell Script: how to read a text file that does not end with a newline on Windows

Instead of reading line-by-line, why not read the whole file at once?

[ -f $FileName ] && fileNameListStr=$( tr '\n' ' ' < $FileName )

bash scripting - while loop not reading next line and storing value as intended

The issue is that you do the replacements on the wrong key. In this if statement

if [[ "$keyname" = "mmsGroupId" && "$value" = "$curr_group" ]]; then
echo "We have a match - $value:$curr_group - NOTHING TO DO"
else
echo "No match found - let us update it"
sed -i 's/mmsGroupId='"$curr_group"'/mmsGroupId='"$value"'/g' /tmp/test.config
fi

The else block was supposed to run when the value in the file is incorrect, but it also runs when the $keyname is wrong.

You could use nested if statements or elif [[ "$keyname" = "mmsGroupId ]] to ensure that the replacement doesn't run on the wrong key.

A better solution is to get rid of the while loop and if statements:

for key in mmsGroupId mmsApiKey
do
value=$(grep "$key" /tmp/source.txt | cut -d "=" -f2);
sed -i "s/$key=.*/$key=$value/" /tmp/test.config
done

While loop stops reading after the first line in Bash

The problem is that do_work.sh runs ssh commands and by default ssh reads from stdin which is your input file. As a result, you only see the first line processed, because the command consumes the rest of the file and your while loop terminates.

This happens not just for ssh, but for any command that reads stdin, including mplayer, ffmpeg, HandBrakeCLI, httpie, brew install, and more.

To prevent this, pass the -n option to your ssh command to make it read from /dev/null instead of stdin. Other commands have similar flags, or you can universally use < /dev/null.

Last line of a file is not reading in shell script

This is due to missing line break in the last line of your input file.

You can use this loop to read everything:

while IFS= read -r line || [ -n "$line" ]; do
echo "$line"
done < "$file"

For the last line without line break, read doesn't return a success hence [ -n "$line" ] check is done to make sure to print it when $line is not empty.

PS: If you don't mind changing your input file then use printf to append a newline using:

printf '\n' >> "$file"

And then read normally:

while IFS= read -r line; do
echo "$line"
done < "$file"

shell script does not read last line from sysin

If you need desperately to read files without EOL in the end, then you may check whether returned string is empty or not instead of checking read exit status:

#!/bin/bash
while true; do
line=''
read line
if [ -z "$line" ]; then
break
fi
echo "$line"
done


Related Topics



Leave a reply



Submit