LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
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


Closed Thread
  Search this Thread
Old 01-17-2017, 08:10 AM   #1
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
BASH fancy test vs if statements how to?


I cannot figure out what search words to get this off of google. So I am coming here to seek my answer(s).

I am wanting to see if I can get this to run faster then it already is by shorting up the code for bash to preform checks before issuing the commands.

This is the current way this code block is written. I do not really need it to check to see if the first two varitables are empty or not. Because I already ensured they are not with puddletag.

Code:
			
	if  [[ -n "$ARTIST" ]] && [[ -n "$ALBUM" ]] &&  [[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]]  ; then
	
	
			echo "Had to make it now moving New File .............."
			echo
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
			
		else
		
			echo
			echo "alread there now moving new file name"
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ 
		
	echo;echo;echo
	echo "MAX   is $max"
	((count++))
	fi
	echo "count is $count"
	left=$(expr $max - $count)
	echo "         --------"
	echo "         $left"
	echo
With this BASH syntext
Code:
	[[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" 
			echo "Had to make it now moving New File .............."
			echo
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
			
		else
		
			echo
			echo "alread there now moving new file name"
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ 
		
	echo;echo;echo
	echo "MAX   is $max"
	((count++))
	fi
	echo "count is $count"
	left=$(expr $max - $count)
	echo "         --------"
	echo "         $left"
	echo
As I figured one cannot add an else to this from of writting test because it lacks the if then
Writting it this way

Code:
	[[ ! -d "$move_to" ]]  && mkdir -pv "$move_to" 	
	
	[[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" 
			echo "Had to make it now moving New File .............."
			echo
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
			
    [[ -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && 
			echo
			echo "alread there now moving new file name"
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ 
		
	echo;echo;echo
	echo "MAX   is $max"
	((count++))
	 
	echo "count is $count"
	left=$(expr $max - $count)
	echo "         --------"
	echo "         $left"
	echo

gets me these results
Code:
+ [[ ! -d /run/media/userx/NTFS600GB/TEST ]]
+ [[ ! -d /run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out (Disc-2) ]]
+ echo 'Had to make it now moving New File ..............'
Had to make it now moving New File ..............
+ echo

+ mv -v '/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out (Disc-2)/Conundrum.mp3' '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out (Disc-2)/'
'/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out (Disc-2)/Conundrum.mp3' -> '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out (Disc-2)/Conundrum.mp3'
+ [[ -d /run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out (Disc-2) ]]
+ echo

+ echo 'alread there now moving new file name'
alread there now moving new file name
+ mv -v '/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out (Disc-2)/Conundrum.mp3' '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out (Disc-2)/'
mv: cannot stat '/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out (Disc-2)/Conundrum.mp3': No such file or directory
It already moves the file reguardless if the test to see if the directroy is not there so then it gets to the is the directroy there and goes to move it it cannot be found because it already movied it. making the first test if not there then create it obsolete. It needs to be created once for the first file then the rest get moved into it after words, But not putting faith in this BASH I run a test to be sure it is there before telling it to move the file to same directory.

I hope I explaned that logic ok.

even when I chance it. getting rid of all of the echo and making it just one liners
Code:
	[[ ! -d "$move_to" ]]  && mkdir -pv "$move_to" 	
	
	[[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" && mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/

( here is where an else  could go eliminating the test becuase if the first test ! -d is false then the directories are already establised. Therefore, else just move the file into that directory/sub-directory)
			
        [[ -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/

I get this
Code:
+ [[ ! -d /run/media/userx/NTFS600GB/TEST ]]
+ [[ ! -d /run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out ]]
+ mkdir -pv '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out'
mkdir: created directory '/run/media/userx/NTFS600GB/TEST/Jethro Tull'
mkdir: created directory '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out'
+ mv -v '/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out/Sweet Dream.mp3' '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out/'
'/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out/Sweet Dream.mp3' -> '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out/Sweet Dream.mp3'
+ [[ -d /run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out ]]
+ mv -v '/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out/Sweet Dream.mp3' '/run/media/userx/NTFS600GB/TEST/Jethro Tull/Live Bursting Out/'
mv: cannot stat '/run/media/userx/NTFS600GB/WorkingDirMP3/Jethro Tull/Live Bursting Out/Sweet Dream.mp3': No such file or directory
as it moved that file already when it goes to check that next test of course the directory is already in place and tries to move a file that has alredy been moved.

SO I am thinking well I got to use the old if then else to get this, or is their a better logical way of doing this so that it will just run faster that I have not thought of yet to do this out there in someone elses head?

I guess I could do it like this: But I was looking to beaf up my BASH with using [[ check for true ]] && do something(s)

Code:
	if [[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] ; then 
			mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" 
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
		else
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
		fi

Does anyone have a link to the documentataion on that from of writting BASH to share?

[[ if test true ]] && do something(s)

Last edited by BW-userx; 01-17-2017 at 08:31 AM.
 
Old 01-17-2017, 09:07 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,830

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
in short you need { } if you want more commands after &&, otherwise condition will only be valid for the first one
Code:
   [[ -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && {
			echo
			echo "alread there now moving new file name"
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ }
 
1 members found this post helpful.
Old 01-17-2017, 09:09 AM   #3
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by pan64 View Post
in short you need { } if you want more commands after &&, otherwise condition will only be valid for the first one
Code:
   [[ -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && {
			echo
			echo "alread there now moving new file name"
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ }
So it does use brackets. I dismissed that idea before trying it. Because it is BASH and not C or similar. Thanks.

But that leaves an else do something "esle" out of the picture.

Code:
[[ true ]] && { do some stuff and some more stuff } else { do something else and some more stuff too}
Suppose I'll see if I can blow something up.

doesn't work
Code:
	[[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && {
			mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" 
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
		}
		else
		{ mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ }
error
Code:
./ResortMP3: line 58: syntax error near unexpected token `else'
./ResortMP3: line 58: `		else'
OK

I think I almost got it, I am still getting one error on the first creation of a Directory due to the next line

Code:
		[[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && {
			mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" 
			mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
		}
		 
		 mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
error
Code:
mkdir: created directory '/run/media/userx/NTFS600GB/Test/Joe Jackson'
mkdir: created directory '/run/media/userx/NTFS600GB/Test/Joe Jackson/Afterlife'
'/run/media/userx/NTFS600GB/WorkingDirMP3/Joe Jackson/Afterlife/Awkwarde Age.mp3' -> '/run/media/userx/NTFS600GB/Test/Joe Jackson/Afterlife/Awkwarde Age.mp3'

(because it was already moved)

mv: cannot stat '/run/media/userx/NTFS600GB/WorkingDirMP3/Joe Jackson/Afterlife/Awkwarde Age.mp3': No such file or directory
I want to eliminte having to check it if is already there because the first block of code made sure it is while keeping it down to the lest amount of lines of code as possible.

Last edited by BW-userx; 01-17-2017 at 09:22 AM.
 
Old 01-17-2017, 09:30 AM   #4
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
what was that one liner that C has? Something like this (its been a while)
Code:
(?:)
(if true ? do this : else do this)
I think that is how it went.

OK I think I found it.

Code:
[[ $b = 5 ]] && a="$c" || a="$d"

BASH Ternary Operators

Last edited by BW-userx; 01-17-2017 at 09:35 AM.
 
Old 01-17-2017, 09:39 AM   #5
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,776

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
No, you cannot use "else" without "if ... then", but you can accomplish it this way:
Code:
[[ some condition ]] && { code block 1; } || { code block 2; }
The catch (familiar to Python programmers) is that you hve to ensure that code block 1 always ends with a "true" condition (zero return code). You can do that by making the last command in code block 1 one that always succeeds, like "true" or ":".

Doing that should be an intellectual exercise only. In the real world, "if ... then ... else ... fi" would be preferable.
 
2 members found this post helpful.
Old 01-17-2017, 09:54 AM   #6
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
NOT WORKING YET

using this example
Code:
[ $b == 5 ] && { a=$c; true; } || a=$d
mine is
Code:
find "$working_dir" -type f -name "*.mp3" | while [[ $count -lt $max ]] ; do
read FILENAME;

(removed unnecessary stuff to see in here)
  [[ ! -d "$move_to" ]]  && mkdir -pv "$move_to" 	
	
 [[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] && { mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" ; mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ } ||  mv -v "${FILENAME}" "$move_to"/"$ARTIST""$ALBUM"/

	echo;echo;echo
	echo "MAX   is $max"
	((count++))
	echo "count is $count"
	left=$(expr $max - $count)
	echo "         --------"
	echo "         $left"
	echo

 
done
I get this error
Code:
./ResortMP3: line 65: syntax error near unexpected token `done'
./ResortMP3: line 65: `done '
This does not work either I am getting the same error. done unexpected.
Code:
if [[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] ; then { mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" ; mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ } else { mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ }	fi

Last edited by BW-userx; 01-17-2017 at 10:05 AM.
 
Old 01-17-2017, 10:20 AM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I would like to step back a little from what is perhaps the actual problem.

1. mkdir -p will already perform its own test if the path exists and create if not or skip, so I am not seeing the point of the test??

2. Testing (or using above) on both $move_to and "$move_to"/"$ARTIST"/"$ALBUM" is again a waste as it will make all required parent directories as needed, or again, skip if they all exist

3. This one is personal, but you only need one set of quotes, eg.
Code:
"$move_to"/"$ARTIST"/"$ALBUM"

#becomes

"$move_to/$ARTIST/$ALBUM" ... which I think is much cleaner
4. I am also not a fan of mixing my arithmetic operations, so either use (()) or expr, eg.
Code:
left=$(expr $max - $count)

#becomes

(( left = max - count ))
5. I would also use above for the while loop test

6. Remember that when piping into a while loop, you will not be able to use any of the variable values outside the loop due to be in a subshell. The alternative would be:
Code:
while (( count < max ))
do
...
done< <(find "$working_dir" -type f -name "*.mp3")
Hope some of that helps. It may also resolve the actual issue you are having ... maybe
 
2 members found this post helpful.
Old 01-17-2017, 10:22 AM   #8
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,776

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Quote:
Originally Posted by BW-userx View Post
Code:
{ mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" ; mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ }
That closing curly brace is only recognized when it's at the start of a command. You need a semicolon after the command that precedes it:
Code:
{ mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" ; mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/; }
                                                                                              ^
 
2 members found this post helpful.
Old 01-17-2017, 10:31 AM   #9
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by rknichols View Post
No, you cannot use "else" without "if ... then", but you can accomplish it this way:
Code:
[[ some condition ]] && { code block 1; } || { code block 2; }
The catch (familiar to Python programmers) is that you hve to ensure that code block 1 always ends with a "true" condition (zero return code). You can do that by making the last command in code block 1 one that always succeeds, like "true" or ":".

Doing that should be an intellectual exercise only. In the real world, "if ... then ... else ... fi" would be preferable.
I am starting to figure that out. Too it seems that the Ternary Operator (? while it does work in BASH if used with two brackets ((?) it can only be used with non-strings comparisons.

Regardless, I am not getting it to work. lol

But according to this

Ternary operator in bash


Their is a way to fake it.
Quote:
Well, there’s no ternary operator in Bash, but there is a way to fake it.

valid=1
[ $valid ] && x=1 || x=0
In here Ternary operator (? in Bash it shows many different ways to perform this task.
one example
Quote:

(( a = b==5 ? c : d )) # string + numeric
But I am not having any success. With any of these one liners. When I place it in a one liner I keep getting an error
Code:
unexpected done
within my while loop

The only one I am getting to work is this one.
Code:
if [[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]] ; then 
	mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" 
	mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
else
	mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/
fi
So I do suppose I'll mark this solved unless someone can give me a one liner that will work within a while loop.

Cheers and thanks!

btw
looking at your code example again after I posted this. I see a difference from what I tried. so I'll give that a try.

OK I did it! yeah!! woo hoo!
Code:
  [[ ! -d "$move_to"/"$ARTIST"/"$ALBUM" ]]  && { mkdir -pv "$move_to"/"$ARTIST"/"$ALBUM" ; mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ ; } || { mv -v "${FILENAME}" "$move_to"/"$ARTIST"/"$ALBUM"/ ; }
I needed one more ; within that first pair of { } at the end to get rid of the unexpected done error along with what you did placing a semi-colon at the end of the second command. ;

Last edited by BW-userx; 01-17-2017 at 10:37 AM.
 
Old 01-17-2017, 10:39 AM   #10
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
@pan64
@rknichols

+1 given thanks!
and to
@grail
for the tips in coding BASH

Last edited by BW-userx; 01-17-2017 at 10:49 AM.
 
Old 01-17-2017, 11:03 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Just to conclude, the simplest one liner is:
Code:
mkdir -pv "$move_to/$ARTIST/$ALBUM" && mv -v "${FILENAME}" "$move_to/$ARTIST/$ALBUM/"
The mkdir will always be true whether it creates the path or not
 
2 members found this post helpful.
Old 01-17-2017, 11:12 AM   #12
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by grail View Post
I would like to step back a little from what is perhaps the actual problem.

1. mkdir -p will already perform its own test if the path exists and create if not or skip, so I am not seeing the point of the test??
I actually didn't know that. Thanks for pointing that out. I only used it to do directory/subdirectory. Habit to check before jumping mode removed.

Quote:

2. Testing (or using above) on both $move_to and "$move_to"/"$ARTIST"/"$ALBUM" is again a waste as it will make all required parent directories as needed, or again, skip if they all exist
yeah I knew it was redundant, but I left it there anyways.


Quote:

3. This one is personal, but you only need one set of quotes, eg.
Code:
"$move_to"/"$ARTIST"/"$ALBUM"

#becomes

"$move_to/$ARTIST/$ALBUM" ... which I think is much cleaner
Done. Good recommendation.

Quote:
4. I am also not a fan of mixing my arithmetic operations, so either use (()) or expr, eg.
Code:
left=$(expr $max - $count)

#becomes

(( left = max - count ))
Changed it to the later.
Quote:
5. I would also use above for the while loop test

6. Remember that when piping into a while loop, you will not be able to use any of the variable values outside the loop due to be in a subshell. The alternative would be:
Code:
while (( count < max ))
do
...
done< <(find "$working_dir" -type f -name "*.mp3")
Hope some of that helps. It may also resolve the actual issue you are having ... maybe
Thanks, I've been not liking doing it that way for some time now. Changed.


My Code it now way shorter than the one liner I just posted got me to mark solved. I went back over this post that is when I noticed yours within it. Gave it a look see took your advice and this is what I ended up with.

Code:
#!/bin/bash

#written Jan 16, 17 2017

 
#set -xv 

typeset -i  count max
let count=0 max=0

#working_dir="/run/media/userx/NTFS600GB/WorkingDirMP3"
working_dir="/run/media/userx/NTFS600GB/Test"

#move_to="/run/media/userx/NTFS600GB/iTunesMusic"
move_to="/run/media/userx/NTFS600GB/TEST"

script_dir="/home/userx/scripts"

max="$(find "$working_dir" -type f -name "*.mp3" | wc -l)"

while (( count < max )) 
do
read FILENAME;

ARTIST="`exiftool -Artist "$FILENAME" -p '$Artist'`"
ALBUM="`exiftool  -Album  "$FILENAME" -p '$Album'`"
 
#ensure only one space between each word
ARTIST="$(echo -e "${ARTIST}" | sed -e 's/\s+/ /g')"
ALBUM="$(echo -e "${ALBUM}" | sed -e 's/\s+/ /g')"

#removes leading white space on both ends of string
ARTIST="$(echo -e "${ARTIST}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
ALBUM="$(echo -e "${ALBUM}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
 
eyeD3 -a "${ARTIST}" "${FILENAME}"
eyeD3 -A "${ALBUM}"  "${FILENAME}"

#create and move file into respective areas

	 mkdir -pv "$move_to/$ARTIST/$ALBUM" 
	 mv -v "${FILENAME}" "$move_to/$ARTIST/$ALBUM" 
	 
        echo
	echo "MAX   is $max"
	((count++))
	echo "count is $count"
 	(( left = max - count ))
	echo "         --------"
	echo "         $left"
	echo
 
done < <(find "$working_dir" -type f -name "*.mp3")
No more test before issuing commands.

Thanks again!

Last edited by BW-userx; 01-17-2017 at 11:35 AM.
 
Old 01-17-2017, 11:37 AM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
No probs ... here are some twists I had on your code:
Code:
#typeset -i  count max
#let count=0 max=0
count=0 max=0

#working_dir="/run/media/userx/NTFS600GB/WorkingDirMP3"
working_dir="/run/media/userx/NTFS600GB/Test"

#move_to="/run/media/userx/NTFS600GB/iTunesMusic"
move_to="/run/media/userx/NTFS600GB/TEST"

script_dir="/home/userx/scripts"

max="$(find "$working_dir" -type f -name "*.mp3" | wc -l)"

while read FILENAME
do

  ARTIST="$(exiftool -Artist "$FILENAME" -p '$Artist')"
  ALBUM="$(exiftool  -Album  "$FILENAME" -p '$Album')"

  #ensure only one space between each word
# ARTIST="$(echo -e "${ARTIST}" | sed -e 's/\s+/ /g')"
  set -- $ARTIST
  ARTIST="$@"
# ALBUM="$(echo -e "${ALBUM}" | sed -e 's/\s+/ /g')"
  set -- $ALBUM
  ALBUM="$@"

  #removes leading white space on both ends of string
# ARTIST="$(echo -e "${ARTIST}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
# ALBUM="$(echo -e "${ALBUM}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"

  eyeD3 -a "$ARTIST" "$FILENAME"

  #create and move file into respective areas

  mkdir -pv "$move_to/$ARTIST/$ALBUM"
  mv -v "$FILENAME" "$move_to/$ARTIST/$ALBUM"

  cat <<-EOF

    MAX   is $max
    count is $((++count))
             --------
             $((max - count))

  EOF
# echo
# echo "MAX   is $max"
# ((count++))
# echo "count is $count"
# (( left = max - count ))
# echo "         --------"
# echo "         $left"
# echo

done < <(find "$working_dir" -type f -name "*.mp3")
The typset and let are again a personal preference but up to you

Take what you like
 
1 members found this post helpful.
Old 01-17-2017, 01:13 PM   #14
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by grail View Post
No probs ... here are some twists I had on your code:
Code:
  cat <<-EOF

    MAX   is $max
    count is $((++count))
             --------
             $((max - count))

  EOF
# echo
# echo "MAX   is $max"
# ((count++))
# echo "count is $count"
# (( left = max - count ))
# echo "         --------"
# echo "         $left"
# echo

done < <(find "$working_dir" -type f -name "*.mp3")
The typset and let are again a personal preference but up to you

Take what you like
Just to check out everything you did for a look see. I get an error.. what? yep an error
Code:
#!/bin/bash

set -x

count=0 max=0

#working_dir="/run/media/userx/NTFS600GB/WorkingDirMP3"
working_dir="/run/media/userx/NTFS600GB/Test"

#move_to="/run/media/userx/NTFS600GB/iTunesMusic"
move_to="/run/media/userx/NTFS600GB/TEST"

script_dir="/home/userx/scripts"

max="$(find "$working_dir" -type f -name "*.mp3" | wc -l)"

while read FILENAME
do

  ARTIST="$(exiftool -Artist "$FILENAME" -p '$Artist')"
  ALBUM="$(exiftool  -Album  "$FILENAME" -p '$Album')"

  #ensure only one space between each word
  set -- $ARTIST
  ARTIST="$@"

  set -- $ALBUM
  ALBUM="$@"

  #removes leading white space on both ends of string

	eyeD3 -a "$ARTIST" "$FILENAME"
	eyeD3 -A "$TITLE" "$FILENAME"
	
  #create and move file into respective areas

  mkdir -pv "$move_to/$ARTIST/$ALBUM"
  mv -v "$FILENAME" "$move_to/$ARTIST/$ALBUM"

  cat <<-EOF

    MAX   is $max
    count is $((++count))
             --------
             $((max - count))

       EOF

done < <(find "$working_dir" -type f -name "*.mp3")
It is showing green in greny color code for bash script.
the error
Code:
[scripts]>>$ ./MP3Sort
+ count=0
+ max=0
+ working_dir=/run/media/userx/NTFS600GB/Test
+ move_to=/run/media/userx/NTFS600GB/TEST
+ script_dir=/home/userx/scripts
++ find /run/media/userx/NTFS600GB/Test -type f -name '*.mp3'
++ wc -l
+ max=349
./MP3Sort: line 49: warning: here-document at line 40 delimited by end-of-file (wanted `EOF')
./MP3Sort: line 50: syntax error: unexpected end of file
[userx@voider.org]:
Not that I understand what it going on with
Code:
  set -- $ARTIST
  ARTIST="$@"

  set -- $ALBUM
  ALBUM="$@"
but that is why I set -x
the EOF is doing what?

you got links to BASH pages that I could look over to educate myself on this?


commenting it out the cat <<-EOF -- to --- EOF - , it runs fine and I see what that set is doing thanks.

Changed the echo count to this
Code:
  #cat <<-EOF

     echo "MAX    is $max"
     echo "count  is $((++count))"
     echo "           --------"
     echo "          $((max - count))"
     
     
     #  EOF
I diffidently see a speed up between files.

Last edited by BW-userx; 01-17-2017 at 01:22 PM.
 
Old 01-17-2017, 01:24 PM   #15
szboardstretcher
Senior Member
 
Registered: Aug 2006
Location: Detroit, MI
Distribution: GNU/Linux systemd
Posts: 4,278

Rep: Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694
For the <<-EOF explanation:

http://man.cx/bash

Under the "Here Documents" section.

And for the set -- explanation:

http://man.cx/set

Search for -- in the page for information.
 
2 members found this post helpful.
  


Closed Thread



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
Help with scripting, aliases, and test statements. ThatCyberGuy Linux - Newbie 4 11-14-2015 02:58 PM
LXer: Bash If statements, Exit Status and Comparison Operators, A beginners guide to bash scripting LXer Syndicated Linux News 0 06-29-2014 07:35 PM
LXer: How to Make a Fancy and Useful Bash Prompt in Linux LXer Syndicated Linux News 0 05-09-2014 07:51 PM
LXer: Bash One-Liner Script To Produce Somewhat-Fancy Output Of Who's On Your Linux O LXer Syndicated Linux News 0 11-19-2008 01:40 AM
urpmi looks for fancy dependency (bash) jfi Mandriva 6 03-05-2004 03:35 PM

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

All times are GMT -5. The time now is 02:52 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