Nested for loop executing weirdly - bash

I'm currently trying to run a check to download an index file for each entry in a csv, match a last downloaded id to the index and see if it's present. But it is currently only executing the last downloaded id once.
checkIndex() {
for log in $(cat "$2/$3/logs.index")
do
temp=$(echo "$1" | tr -d '\r')
echo "$temp"
if [ $temp == $log ]; then
return 1
fi
done
sed 1d $csvfile | while IFS=, read -r site id key url conf
do
conf=$(echo "$conf" | tr -d '\r')
curr=$(cat "$CONF_DIR$conf/LastKnownDownloadedFileId_curr.txt")
site=$(echo "$site" | tr -d '\r')
id=$(echo "$id" | tr -d '\r')
key=$(echo "$key" | tr -d '\r')
url=$(echo "$url" | tr -d '\r')
index="logs.index"
echo "$site $id $key $url $conf"
if [ ! -d "$TEMPDIR/$site" ]; then
mkdir -p "$TEMPDIR/$site"
fi
wget -q --user=$id --password=$key $url$index -O $TEMPDIR/$site/logs.index
checkIndex $curr $TEMPDIR $site
However the output is something like this
testsite testid testkey https://testurl/ testconf
9248_2147.log vs 9248_2049.log
9248_2050.log
9248_2051.log
9248_2052.log
9248_2053.log
9248_2054.log
9248_2055.log

Sorry all! turns out it was an issue of declaring IFS="," at the top of my script. I was trying to remove unneeded code and after removing IFS="," it worked properly.

Related

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

I'm doing a script to parse m3u files.
The goal is to retrieve the variable tag and the url.
I tested with this file.
#!/bin/bash
echo "name,tvg-id,tvg-name,tvg-country,group-title,languages,url"
while IFS= read -r line; do
tags_detect="$(echo "$line" | grep -Eo '^#EXTINF:')"
if [[ -n ${tag_detect} ]]; then
get_chno="$(echo "$line" | grep -o 'tvg-chno="[^"]*' | cut -d '"' -f2)"
get_id="$(echo "$line" | grep -o 'tvg-id="[^"]*' | cut -d '"' -f2)"
get_logo="$(echo "$line" | grep -o 'tvg-logo="[^"]*' | cut -d '"' -f2)"
get_grp_title="$(echo "$line" | grep -o 'group-title="[^"]*' | cut -d '"' -f2)"
get_title="$(echo "$line" | grep -o ',[^*]*' | cut -d ',' -f2)"
get_tvg_name="$(echo "$line" | grep -o 'tvg-name="[^"]*' | cut -d '"' -f2)"
get_country="$(echo "$line" | grep -o 'tvg-country="[^"]*' | cut -d '"' -f2)"
get_language="$(echo "$line" | grep -o 'tvg-language="[^"]*' | cut -d '"' -f2)"
phrase="${get_title},${get_id},${get_tvg_name},${get_country},${get_grp_title},${get_language}"
else
url="$line"
fi
echo "${phrase},${url}"
done <"${1}"
So, Without "If" it works but i don't have url.
I add a "IF" and ... :
,#EXTM3U
4 Turk Music,4TurkMusic.fr,4 Turk Music,FR;TK,Music,Turkish,#EXTM3U
4 Turk Music,4TurkMusic.fr,4 Turk Music,FR;TK,Music,Turkish,http://51.210.199.30/hls/stream.m3u8
Alpe d’Huez TV,AlpedHuezTV.fr,Alpe d’Huez TV,FR,,French,http://51.210.199.30/hls/stream.m3u8
Alpe d’Huez TV,AlpedHuezTV.fr,Alpe d’Huez TV,FR,,French,https://edge10.vedge.infomaniak.com/livecast/ik:adhtv/chunklist.m3u8
... It's broken and I don't found my error.
desired output:
4 Turk Music,4TurkMusic.fr,4 Turk Music,FR;TK,Music,Turkish,http://1.2.3.4/hls/stream.m3u8
Alpe d’Huez TV,AlpedHuezTV.fr,Alpe d’Huez TV,FR,,French,https://edge10.vedge.infomaniak.com/livecast/ik:adhtv/chunklist.m3u8
I don't understand my mistake.
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
You probably better use a more capable language like Perl.
#! /usr/bin/perl
use strict;
use warnings;
print "name,tvg-id,tvg-name,tvg-country,group-title,languages,url\n";
my %tags;
my $title;
while (<>)
{
next if /^#EXTM3U/;
if (s/^#EXTINF:-1//) {
%tags = ();
$tags{$1} = $2 while (s/\s*(\S+)="([^"]*)"//);
($title) = $_ =~ /,(.*)/;
} else {
print join (',', $title,
$tags{'tvg-id'},
$tags{'tvg-name'},
$tags{'tvg-country'},
$tags{'group-title'},
$tags{'tvg-language'},
$_);
}
}
A quick refactor (untested) -
declare -A tag
while IFS= read -r line; do
case "$line" in
\#EXTINF:*)
if [[ "$line" =~ ,([^*]+) && -n "${BASH_REMATCH[0]}" ]]; then
tag[title]="${BASH_REMATCH[0]}"
phrase="${tag[title]}"
fi
for id in tvg-id tvg-name tvg-country group-title tvg-language tvg-chno tvg-logo; do
pat=$id'="([^"]+)"'
[[ "$line" =~ $pat ]] && tag[$id]="${BASH_REMATCH[0]}";
phrase="$phrase,${tag[$id]}"
done
phrase="${phrase%,${tag[tvg-chno]},${tag[tvg-logo]}}"
;;
*) url="$line"
esac
echo "${phrase},${url}"
done <"${1}"
Needs a lot more error checking...

How can I get a number from user in telegram bot?

example
I want to make something like 'a button, when the user press this button A question will appear to him: Do you want to share your contact with the bot?,' I want like this using curl in bash script:
and I try like this, but it is doesn't working
#!/bin/bash
clear
token=""
old=$(curl -s "https://api.telegram.org/bot$token/getUpdates" | awk 'END{print}' | sed -n -e 's/^.*"date"://p' | cut -d ',' -f1)
while true; do
new=$(curl -s "https://api.telegram.org/bot$token/getUpdates" | awk 'END{print}')
if [[ "$new" =~ \"chat\"\:\{\"id\"\:([\-0-9]+)\, ]]; then
CHATID=${BASH_REMATCH[1]};
fi
if [[ "$new" =~ \"date\"\:([0-9]+)\, ]]; then
DATE=${BASH_REMATCH[1]};
fi
TEXT=$(echo "$new" | sed -n -e 's/^.*"text":"//p' | cut -d '"' -f1)
if ! [ "$DATE" = "$old" ]; then
echo "text: $TEXT, from: $USERNAME, id: $CHATID"
if [ "$TEXT" = "/start" ]; then
curl "https://api.telegram.org/bot$token/KeyboardButton?chat_id=$CHATID&text=flase&request_contact=true"
fi
old="$DATE"
fi
done
And error code is:
{"ok":false,"error_code":404,"description":"Not Found"}%
I try like this but It's now working how can I done this in right way?
https://i.stack.imgur.com/HQ8ga.jpg

if statement throws error as end of file

i have a script that looks something like
#!/bin/bash$
#x=new value$
#y=old value$
$
export PATH=/xxx/xxx/xxx:$PATH$
$
#get the difference of two files$
diff --side-by-side --suppress-common-lines file.txt file1.txt | tr -d "|,<,>,'\t'" | sed 's/ /:/g' | sed 's/^://' > diff.txt$
cat diff.txt$
$
#get the values$
for i in `cat diff.txt`; do$
plug_x=`echo $i | cut -d ":" -f1`$
echo "the value of jenkins plugin is $plug_x"$
ver_x=`echo $i | cut -d ":" -f2`$
echo "the value of jenkins version is $ver_x"$
plug_y=`echo $i | cut -d ":" -f3`$
echo "the value of db plugin is $plug_y"$
ver_y=`echo $i | cut -d ":" -f4`$
echo "the value of db version is $ver_y"$
if [ -z "$ver_y" ] && [ -z "$ver_x" ] ;$
then $
echo "the plugin is newly added"$
#newly added plugin should be updated in the db$
# mysql -u root -ppassword -h server --local-infile db << EOFMYSQL$
#update the table with the new version$
#EOFMYSQL$
else$
echo "the plugin has changes"$
mysql -u root -ppassword -h server --local-infile db << EOFMYSQL$
insert into table (xxx, xxx) values('$ver_x','$plug_x');$
$
EOFMYSQL $
fi$
done$
but when i run this script it saya
Syntax error: end of file unexpected (expecting "fi")
but the fi is there..i cant figure out why it is throwing the error
this error does not come when i just have echo statements in the script
I would suggest that if you are just running that one query to insert into table, then echo the query and pipe it to the mysql command, that would be (in my opinion) a better and efficient choice.
#!/bin/bash
diff --side-by-side --supress-common-lines test1.txt test2.txt | tr -d "|,<,>,'\t'" | sed 's/ /:/g' | sed 's/^://' > ./diff.txt
for i in `cat ./diff.txt`; do
plug_x=`echo $i | cut -d ":" -f1`
echo "the value of jenkins plugin is $plug_x"
ver_x=`echo $i | cut -d ":" -f2`
echo "the value of jenkins version is $ver_x"
plug_y=`echo $i | cut -d ":" -f3`
echo "the value of db plugin is $plug_y"
ver_y=`echo $i | cut -d ":" -f4`
echo "the value of db version is $ver_y"
if [ -z "$ver_y" ] && [ -z "$ver_x" ]
then
echo "the plugin is newly added"
else
echo "the plugin has changes"
echo "insert into table (xxx, xxx) values('$ver_x','$plug_x')" | mysql -u root -ppassword -h server --local-infile db
fi
done
That should do the job or if you'd like to use While loop, you can certainly do so.
#!/bin/bash
diff --side-by-side --supress-common-lines test1.txt test2.txt | tr -d "|,<,>,'\t'" | sed 's/ /:/g' | sed 's/^://' > ./diff.txt
cat ./diff.txt | while read i
do
plug_x=`echo $i | cut -d ":" -f1`
echo "the value of jenkins plugin is $plug_x"
ver_x=`echo $i | cut -d ":" -f2`
echo "the value of jenkins version is $ver_x"
plug_y=`echo $i | cut -d ":" -f3`
echo "the value of db plugin is $plug_y"
ver_y=`echo $i | cut -d ":" -f4`
echo "the value of db version is $ver_y"
if [ -z "$ver_y" ] && [ -z "$ver_x" ]
then
echo "the plugin is newly added"
else
echo "the plugin has changes"
echo "insert into table (xxx, xxx) values('$ver_x','$plug_x')" | mysql -u root -ppassword -h server --local-infile db
fi
done

bash script prints "No such file or directory" when comparing filenames to string

I am checking to see if a file I am hoping to create conflicts with a file that has the same name.
FILEPATH=/root/logs/pData*.csv
COMPPATH=/root/logs/pData*.csv.gz
shopt -s nullglob
thisYear="$(date +"%Y")"
thisMonth="$(date +"%m")"
thisDay="$(date +"%d")"
thisTime="$(date | cut -d ' ' -f 4 | tr : _)"
for file in $FILEPATH
do
fileYear="$(stat -c %y $file | cut -d'-' -f 1)"
fileMonth="$(stat -c %y $file | cut -d'-' -f 2)"
fileDay="$(stat -c %y $file | cut -d'-' -f 3 | cut -d' ' -f 1)"
fileTime="$(stat -c %y $file | cut -d ' ' -f 2 | cut -d '.' -f 1 | tr : _)"
if (("$fileYear" < '1990'))
then
fName="pData_"$thisYear"_"$thisMonth"_"$thisDay"_"$thisTime".csv.gz"
else
fName="pData_"$fileYear"_"$fileMonth"_"$fileDay"_"$fileTime".csv.gz"
fi
echo $fName
for file in $COMPPATH
do
if ('/root/logs/'$fName == $file)
then
echo "OOPS"
fi
done
done
The script works as intended for the most part, printing OOPS when I run into a file of the same name, but for files that don't exist it prints
./compress.sh: line 31: /root/logs/pData_2015_09_18_22_25_44.csv.gz: No such file or directory
Why is this printed?
How do I prevent this from happening?
The string comparison is wrong. Using single parentheses is creating a sub-shell and trying to execute '/root/logs/'$fName
Set your string compare to be:
if [[ '/root/logs/'$fName = $file ]]
See: http://www.tldp.org/LDP/abs/html/comparison-ops.html

bash script pulling variables from .txt, keeps giving syntax error while trying to use mount command

Ive been trying to get this to work for the last week and cannot figure out why this is not working. I get mixed results typing directly into the terminal, but keep getting syntax error messages when running from the .sh. using ubuntu 11.10
It looks like part of the mount command gets pushed to the next line not allowing it to complete properly.. I have no idea why this is happening or how to prevent it from going to the second line.
i have several lines defined as follows in mounts.txt, that gets read from mount-drives.sh below
I have called it to run using sudo so it shouldnt be a permissions issue.
Thanks for taking a look, let me know if additional info is needed.
mounts.txt
mountname,//server/share$,username,password,
mount-drives.sh ---origional, updated below
#!/bin/bash
while read LINE;
do
# split lines up using , to separate variables
name=$(echo $LINE | cut -d ',' -f 1)
path=$(echo $LINE | cut -d ',' -f 2)
user=$(echo $LINE | cut -d ',' -f 3)
pass=$(echo $LINE | cut -d ',' -f 4)
echo $name
echo $path
echo $user
echo $pass
location="/mnt/test/$name/"
if [ ! -d $location ]
then
mkdir $location
fi
otherstuff="-o rw,uid=1000,gid=1000,file_mode=0777,dir_mode=0777,username=$user,password=$pass"
mount -t cifs $otherstuff $path $location
done < "/path/to/mounts.txt";
mount-drives.sh ---updated
#!/bin/bash
while read LINE
do
name=$(echo $LINE | cut -d ',' -f 1)
path=$(echo $LINE | cut -d ',' -f 2)
user=$(echo $LINE | cut -d ',' -f 3)
pass=$(echo $LINE | cut -d ',' -f 4)
empty=$(echo $LINE | cut -d ',' -f 5)
location="/mount/test/$name/"
if [ ! -d $location ]
then
mkdir $location
fi
mounting="mount -t cifs $path $location -o username=$user,password=$pass,rw,uid=1000,gid=1000,file_mode=0777,dir_mode=0777"
$mounting
echo $mounting >> test.txt
done < "/var/www/MediaCenter/mounts.txt"
Stab in the dark (after reading the comments). The "$pass" is picking up a newline because the mounts.txt was created in windows and has windows line endings. Try changing the echo $pass line to:
echo ---${pass}---
and see if it all shows up correctly.
There's a lot here that could stand improvement. Consider the following -- far more compact, far more correct -- approach:
while IFS=, read -u 3 -r name path user pass empty _; do
mkdir -p "$location"
cmd=( mount \
-t cifs \
-o "rw,uid=1000,gid=1000,file_mode=0777,dir_mode=0777,username=$user,password=$pass" \
"$path" "$location" \
)
printf -v cmd_str '%q ' "${cmd[#]}" # generate a string corresponding with the command
echo "$cmd_str" >>test.txt # append that string to our output file
"${cmd[#]}" # run the command in the array
done 3<mounts.txt
Unlike the original, this will work correctly even if your path or location values contain whitespace.

Resources