While Loop in Bash Script

While loop in Bash script?

You can't have an empty loop. If you want a placeholder, just use true.

#!/bin/bash
while read myline
do
true
done

or, more likely, do something useful with the input:

#!/bin/bash
while read myline
do
echo "You entered [$line]"
done

As for your second question, on how to exit the loop when the user just presses ENTER with nothing else, you can do something:

#!/bin/bash
read line
while [[ "$line" != "" ]] ; do
echo "You entered [$line]"
read line
done

How to use while loop in bash

You need an arithmetic statement (two parentheses), not a subshell. let is unnecessary here.

i=$1
while (( i < 4 )); do
...
done

while's argument is a shell command. ( i < 4 ) starts a subshell which runs the command i, reading input from a file named 4. The redirection is processed before the command is looked up, which explains why you don't get a i: command not found error.

You can simply replace 4 with the expression you want to use:

while (( i < $1 + $2 )); do

Bash script command not found error in while loop

You are missing space near square brackets used in while loop such as below -

declare -i disk_usage_rate=$(df -h /appdata/SCT_CDR | cut -d '%' -f 1 | awk 'NR==2{print $5}')

while [ "$disk_usage_rate" -gt 80 ]
do
...
...
done

A bit of history: this is because '[' was historically not a
shell-built-in but a separate executable that received the expresson
as arguments and returned a result. If you didn't surround the '['
with space, the shell would be searching $PATH for a different
filename (and not find it) . – Andrew Medico Jun 24 '09 at 1:13

Ref - bash shell script syntax error

While loop in shell script not working in the linux bash shell

The shebang must be set to the shell that should interpret the script. It doesn't matter which shell you run the script from. The only thing that matters is the language the script is written in.

Your script is written in csh, and must therefore have the shebang #!/bin/csh. This is true even if you want to run it from bash. Also, you were missing a space in your at-sign-ment:

$ cat me.csh
#!/bin/csh
set i = 1
echo it starts

while ($i <= 5)
echo i is $i
@ i = $i + 1
end

Output:

$ ./me.csh
it starts
i is 1
i is 2
i is 3
i is 4
i is 5

Speed up bash script while loop

If you want to speed-up the script, consider to use awk instead of bash as Shellter comments. Then would you please try:

hexdump -v -e '8/1 "%02x " "\n"' samples.bin | awk '
BEGIN {
print " ch0 ch1 ch2 ch3" # print the header line
}
{
printf("Sample %d:", NR - 1) # print the sample number
printf(substr(" ", 1, 8 - length(NR - 1))) # adjust the length of the spaces
for (i = 1; i <= NF; i+=2) { # print every two nibbles
j = i + 1
printf("0x%s%s%s", $i, $j, j == NF ? ORS : OFS)
}
}
'

Output with the provided file:

                ch0    ch1    ch2    ch3
Sample 0: 0x1a03 0x1a03 0x4a03 0x5703
Sample 1: 0x4b03 0x4403 0x1e03 0x0904
Sample 2: 0x1003 0x1903 0x4003 0xae03
Sample 3: 0x1e03 0x2603 0x3303 0xad03
Sample 4: 0x1003 0x8403 0x4303 0x6203

The -v option tells hexdump to display all input data instead of summarizing with an asterisk meaning same as the line above.

Bash script, if statement in while loop, unwanted duplicate output

It's broken and I don't found my error.

Paste you script at https://shellcheck.net for validation/recommendation.


Here is how I would do it in bash.

#!/usr/bin/env bash

printf '%s\n' "name,tvg-id,tvg-name,tvg-country,group-title,languages,url"

while IFS= read -r data; do
[[ $data != '#EXTINF:-1'* ]] && continue
IFS= read -r url && [[ $url != 'http'* ]] && echo "$url" && continue
if [[ "$data" == '#EXTINF:-1'* && "$url" == 'http'* ]]; then
title=${data#*\",}
tvg_id=${data#*tvg-id=\"} tvg_id=${tvg_id%%\"*}
tvg_name=${data#*tvg-name=\"} tvg_name=${tvg_name%%\"*}
tvg_country=${data#*tvg-country=\"} tvg_country=${tvg_country%%\"*}
group_title=${data#*group-title=\"} group_title=${group_title%%\",*}
tvg_language=${data#*tvg-language=\"} tvg_language=${tvg_language%%\"*}
printf '%s,%s,%s,%s,%s,%s,%s\n' "$title" "$tvg_id" "$tvg_name" "$tvg_country" "$group_title" "$tvg_language" "$url"
fi
done < file.txt

Although I'm not sure what should happen at line 233 and 238 those lines starts with #EXTVLCOPT


An ed solution if available/acceptable.

The script, name it anything you like. I'll just name it script.ed

g/^#EXTINF:-1/s/$/ /\
;/^http\(s\)\{0,1\}.*/-1;/^[^#]*$/j
,s/^#EXTINF:-1 tvg-id="\([^"]*\)" tvg-name="\([^"]*\)" tvg-country="\([^"]*\)" tvg-language="\([^"]*\).* group-title="\([^"]*\)",\(.*\) \(http.*\)\{0,1\}/\6,\1,\2,\3,\5,\4,\7/
1c
name,tvg-id,tvg-name,tvg-country,group-title,languages,url
.
,p
Q

Now run it against the file in question.

ed -s file.txt < script.ed
  • Remove the ,p from the script to silence the output to stdout or if you're satisfied with the output.

  • Change Q to w from the script if in-place editing is needed.


Should give more or less same result as the bash solution, but since it is still unknown what should happen at line 233 and 238 those lines starts with #EXTVLCOPT

While loop and If statement in Bash script

If you are ok with another solution, then you could try following. Which is efficient than shell solution.

awk '
$0=="char"{
line=FNR
}
END{
print "Last line number having string char is: " line
}
' Input_file

I am also checking your code and will post in few mins on same.



On OP's script: When I tested OP's script and ran it on my aws Ubuntu machine it runs fine as follows.

cat file.ksh
#!/bin/bash

lastline=0
ctr=0

input="test.txt"
while IFS= read -r line
do
((ctr=ctr+1))
### echo "$ctr"
if [ "$line" == "char" ]; then
lastline=$ctr
fi
done < "$input"

echo "$lastline"

./file.ksh
4

Suggestion to OP: Try to check if in case your Input_file named test.txt has Control M characters by doing cat -v test.txt if you see them then remove them by doing tr -d '\r' < test.txt > temp && mv temp test.txt



Related Topics



Leave a reply



Submit