LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-23-2021, 11:38 AM   #1
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 324

Rep: Reputation: Disabled
Variable lost in loop


I have been looking into the code all day and i can not find the reason for this .

Maybe some people here have a different output .
One of my variables do not show up when i use echo to write in on a file , but if i call that variable alone in the code to display only then it will show up correctly .

I am building this script to catalog all music files in my database , this is only a portion of it because the issue is here in this part .

What does this full script does :

This full script will search for m3u , cue , flac and wav files over specific locations (pre configured) or single location depending on user desire , after catching all that data will put all those directories in one file and then will start executing each directory on wich file is there , case is a cue file then will run a cue function , m3u file will run m3u function , etc ... , after parsing all that from cue , m3u file will write the artists and song names to a database.csv
the information writen on the database is :
Artist name , Song name , Location of that file in the server

I dont know why , but i can only get the location of the files written in database , the artist and song name are not written when i use echo with the variables to write in $db , but if before writing i call after each sed call what it have inside that variable then it is fine .

an example of what is going on on the first part of the script i wrote is something like this :

Quote:
a=some.file
b=other.file

if i want 2 variables for 2 calls i will make sed do , usually i will write :

var1=$(sed -n 3p "$a") -> this will read line 3 of file some.file

then i echo that variable to be written like :
echo "$var1" > another.file


in normal circunstance this works fine , but in my script ahead i can not get those values written in database or $db , only the 3rd , and i checked the files and everything is fine , no empty spaces , no empty lines , nothing . I just loose the variables in echo command without reason .
Variable $drd its the location on my system where that file is .

$art = file art.tmp -> look image for output of them
$song = file song.tmp -> look image for output of them
Code:
chkart=$(wc -l "$art" | awk '{print$1}')
if [[ "$chkart" -ge "2" ]]
then
sed -i -e '1d' "$art"
cntsng=$(wc -l "$song" | awk '{print$1}')
for i in $(seq "$cntsng")
do
# ITs various artists
performer=$(sed -n "${i}p"  "$art")
title=$(sed -n "${i}p" "$song")
chkdb=$(wc -c "$db" | awk '{print$1}')
if [[ "$chkdb" -eq "0" ]]
then
echo "$performer - $title , $drd" > "$db"
else
echo "$performer - $title , $drd" >> "$db"
fi
done
else # Album
cntnew=$(wc -l "$song" | awk '{print$1}')
for i in $(seq "$cntnew")
do
title=$(sed -n "${i}p" "$song")
performer=$(sed -n 1p "$art")
chkdb=$(wc -c "$db" | awk '{print$1}')
if [[ "$chkdb" -eq "0" ]]
then
echo "$performer - $title , $drd" > "$db"
else
echo "$performer - $title , $drd" >> "$db"
fi
done
fi
In the image i cat the files that sed was reading and everything is fine , but the output data.csv just show 1 variable , and not all 3 .

On my database output i only get the location where that specific file is , i dont get artist name and song .

Please check the image6 attached here where i show the code on bottom and the output in terminal
Attached Thumbnails
Click image for larger version

Name:	linuxq.jpg
Views:	12
Size:	131.0 KB
ID:	37552   Click image for larger version

Name:	Image6.jpg
Views:	11
Size:	63.4 KB
ID:	37554  

Last edited by pedropt; 10-23-2021 at 01:41 PM.
 
Old 10-23-2021, 12:28 PM   #2
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 1,780

Rep: Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456Reputation: 1456
Quote:
Originally Posted by pedropt View Post
this is only a portion of it because the issue is here in this part .

Variable $drd its the location on my system where that file is .
The four references to "drd" in your snippet are all outputs - you are never assigning a value to drd.


Quote:
In the image i cat the files that sed was reading and everything is fine , but the output data.csv just show 1 variable , and not all 3 .

On my database output i only get the location where that specific file is , i dont get artist name and song .
Run your script through https://www.shellcheck.net/ - it reports your snippet has undefined variables and they correspond to what you say is not working.

 
Old 10-23-2021, 12:42 PM   #3
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 324

Original Poster
Rep: Reputation: Disabled
Thanks for the reply , everything is declared and used , but this is a long script and i only posted the part i am having issues .
For your consideration i am posting the image of shellcheck on the full script just to get any doubts of variables out of the way here .
and some warning there are because the script is not full yet , i stopped there because i had that issue .
Attached Thumbnails
Click image for larger version

Name:	linux3.jpg
Views:	8
Size:	83.9 KB
ID:	37553  

Last edited by pedropt; 10-23-2021 at 12:43 PM.
 
Old 10-23-2021, 01:23 PM   #4
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,035

Rep: Reputation: Disabled
I would rewrite the code like this
Code:
#!/bin/bash
art=art.tmp
song=song.tmp
drd='/media/Disk5/Flac/Albums & Remixed/Alan Barry - Greatest Hits & Remixes (2019)/Alan Barry - Greatest Hits & Remixes CD1'
db=data.csv

mapfile -t titles <"$song"
chkart=$(wc -l <"$art")
((chkart>2)) && skip='-s1' || skip=
mapfile -t $skip performers <"$art"
performer="${performers[0]}"

for ((i=0; i<"${#titles[@]}"; i++))
do
  [[ -n $skip ]] && performer="${performers[$i]}"
  if [[ -s $db ]]
  then echo "$performer - ${titles[$i]} , $drd" >> "$db"
  else echo "$performer - ${titles[$i]} , $drd" > "$db"
  fi
done

Last edited by shruggy; 10-23-2021 at 03:03 PM.
 
Old 10-23-2021, 01:43 PM   #5
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 324

Original Poster
Rep: Reputation: Disabled
Thanks for the reply , i am trying to figure out where is the issue .
Everyone reading please check on the first post the image 6 where it shows the code and what i get in terminal , maybe its more easier to figure out the issue .
 
Old 10-23-2021, 01:55 PM   #6
michaelk
Moderator
 
Registered: Aug 2002
Posts: 22,081

Rep: Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430
Standby I messed up...

Last edited by michaelk; 10-23-2021 at 02:00 PM.
 
Old 10-23-2021, 02:07 PM   #7
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,035

Rep: Reputation: Disabled
I messed up, too. Corrected my post above.

@OP. Now it works with your sample data.

Last edited by shruggy; 10-23-2021 at 02:18 PM.
 
Old 10-23-2021, 02:28 PM   #8
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 324

Original Poster
Rep: Reputation: Disabled
I think the issue is the echo command limitation of character lenght , echo as a maximum output of 200 characters .
Is there any way to write to file on 1 single line more than 200 characters ?
 
Old 10-23-2021, 02:35 PM   #9
michaelk
Moderator
 
Registered: Aug 2002
Posts: 22,081

Rep: Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430
All I can guess at the moment is that chkart is always greater>2 and that your executing code as true and therefore $performer is empty. I have not figured out why song is empty.
 
Old 10-23-2021, 02:37 PM   #10
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,035

Rep: Reputation: Disabled
Quote:
Originally Posted by pedropt View Post
I think the issue is the echo command limitation of character length, echo as a maximum output of 200 characters.
You're wrong, echo doesn't have such a limitation
Code:
echo $(seq 300)

Last edited by shruggy; 10-23-2021 at 02:40 PM.
 
Old 10-23-2021, 02:44 PM   #11
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 324

Original Poster
Rep: Reputation: Disabled
If you look into image6 in first post you will get a different idea , no that is not the issue .
Dont look into all that code , because that is aonly a portion of the script , you dont need to know what is happening before that code , what is needed is to know is why in image6 i can print in display the variables 1 by 1 without issues , but when i call all 3 to same line it only shows me the last one .

Look into image6 on first post please .

Note: I totally understand that it is hard for you guys to understand because it is only a portion of script , but concentrate only in what image shows , when i inserted those echo commands to show me on display if variables are empty before writing or not , and in fact they are not empty , but all 3 i can not manage it to make it work .

By the way , on shruggy code it will not work either because it is not a question of empty variables , the problem is that echo command is unable to print the lenght of all 3 variables .

Last edited by pedropt; 10-23-2021 at 02:45 PM.
 
Old 10-23-2021, 02:49 PM   #12
michaelk
Moderator
 
Registered: Aug 2002
Posts: 22,081

Rep: Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430Reputation: 4430
You can echo way more the 200 characters...
 
Old 10-23-2021, 02:52 PM   #13
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,035

Rep: Reputation: Disabled
Quote:
Originally Posted by pedropt View Post
By the way, on shruggy code it will not work either
Have you tried it? The difference is my code doesn't require the file data.csv to exist beforehand, but yours does:
Code:
$ ls data.csv
ls: cannot access 'data.csv': No such file or directory
$ wc -c data.csv|awk '{print$1}' 
wc: data.csv: No such file or directory
A hint: in your first screenshot the artist is Bosson, but data.csv shows the path for Alan Barry. I suppose either the file doesn't get written at all or you show the wrong file.

Last edited by shruggy; 10-23-2021 at 03:15 PM.
 
Old 10-23-2021, 03:16 PM   #14
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 324

Original Poster
Rep: Reputation: Disabled
one of the problems ahead is that is that your code only will work with Albums , in case of a compilation it will mess up , if you look closer here you will see that if artists are bigger than 1 then the first line is removed from artists file , and the reason is because the first line in a collection is the name of the collection , and i dont want that messed up with songs names , in song names it is deleted automatically when i parse the cue file , if you look into a cue file , the first entry of title is the name of the album or compilation also , exists in both of them .

And by the way , no one yet figured out why echo can not write in my code .

Code:
wrtcue () {
rm "$art" >/dev/null 2>&1
rm "$song" >/dev/null 2>&1
grep "PERFORMER" "$scue" | sed 's/PERFORMER//' | sed 's/"//g' | sed 's/^ *//g' | sed '/^[[:space:]]*$/d' | uniq > "$art"
grep "TITLE" "$scue" | sed 's/TITLE//' | sed 's/"//g' | sed 's/^ *//g' | sed '/^[[:space:]]*$/d' | sed -e '1d' > "$song"
chkart=$(wc -l "$art" | awk '{print$1}')
if [[ "$chkart" -ge "2" ]]
then
sed -i -e '1d' "$art" #in here i removed the first line because it is more than 1 artist , so its a compilation
cntsng=$(wc -l "$song" | awk '{print$1}')
for i in $(seq "$cntsng")
do
# Its various artists
performer=$(sed -n "${i}p"  "$art")
title=$(sed -n "${i}p" "$song")
chkdb=$(wc -c "$db" | awk '{print$1}')
if [[ "$chkdb" -eq "0" ]]
then
echo "$performer - $title , $drd" > "$db"
else
echo "$performer - $title , $drd" >> "$db"
fi
done
else # Album
cntnew=$(wc -l "$song" | awk '{print$1}')
for i in $(seq "$cntnew")
do
title=$(sed -n "${i}p" "$song")
performer=$(sed -n 1p "$art")
chkdb=$(wc -c "$db" | awk '{print$1}')
if [[ "$chkdb" -eq "0" ]]
then
echo "$performer - $title , $drd" > "$db"
else
echo "$performer - $title , $drd" >> "$db"
fi
done
fi
}

Last edited by pedropt; 10-23-2021 at 03:21 PM.
 
Old 10-23-2021, 03:25 PM   #15
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,035

Rep: Reputation: Disabled
I corrected my code in the post above again, so it should work with collections now.

BTW, to print information from a CUE file, you may use cueprint from package cuetools.

Last edited by shruggy; 10-23-2021 at 03:42 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Unable to use variable (i) from loop with FOR in a another variable pedropt Programming 5 12-25-2017 12:31 PM
[SOLVED] [BASH] non-empty variable before loop end, is empty after exiting loop aitor Programming 2 08-26-2010 10:57 AM
AWK a variable Ouptut to a new variable and using the new variable with the old one alertroshannow Linux - Newbie 4 02-16-2009 01:08 AM
for loop only works properly on first loop symo0009 Programming 1 12-25-2005 06:17 PM
while loop or for loop? mijohnst Programming 18 11-21-2005 05:48 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration