ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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"/
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?
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.
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 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
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.
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. ;
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 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
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.