LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   What Does " */./* "mean? (https://www.linuxquestions.org/questions/linux-newbie-8/what-does-%2A-%2A-mean-4175522593/)

Sumguy 10-19-2014 12:27 AM

What Does " */./* "mean?
 
So I figgered[sic] out how to run Mplayer from the terminal, and to specify that it play all files in all folders in a specified directory- now that I know HOW to do it, I want to know WHY it works.

I type this:

Code:

mplayer -shuffle ~/music/oldmusic/directorycontainingsubdirectories/*/./*.mp3
This enables me to shuffle all the files contained in the 66 subdirectories....

I don't understand what the
Code:

*/./*
means.

I know it's something simple- the * is like a wildcard that means "everything", right? What is the "." for? What exactly is */./* saying?

[Cool thing is, I made an alias, so I can just type one word, and BOOM! Mplayer starts playing the files mentioned above. Man, I LOVE Linux!]

astrogeek 10-19-2014 01:11 AM

Quote:

Originally Posted by Sumguy (Post 5255862)
So I figgered[sic] out how to run Mplayer from the terminal, and to specify that it play all files in all folders in a specified directory- now that I know HOW to do it, I want to know WHY it works.

I type this:

Code:

mplayer -shuffle ~/music/oldmusic/directorycontainingsubdirectories/*/./*.mp3
This enables me to shuffle all the files contained in the 66 subdirectories....

I don't understand what the
Code:

*/./*
means.

Unless mplayer has some esoteric path specifications, I would take that to mean...

Code:


~/music/oldmusic/directorycontainingsubdirectories/*/./*.mp3

all subdirectories and all mp3 files in those subdirectories.

which should be the same thing as...

~/music/oldmusic/directorycontainingsubdirectories/*/*.mp3

'./' simply means "this directory"

So I think that the './' is redundant. Try it without the './' in the path and see what happens.

grail 10-19-2014 01:11 AM

Yes * is a glob to get all in a directory (not including hidden files).

. on its own is the current directory, just as .. is the directory above

in the context of */./*.mp3 I do not see a need for the ., so I believe you could have just written */*.mp3

Mr. Alex 10-19-2014 02:15 AM

Code:

less ./././././././././././././././example.txt
will simply open "./example.txt", so the command above equals

Code:

less example.txt

Sumguy 10-19-2014 08:24 AM

You guys nailed it!

I tried it without the /./ and it worked just the same.
Code:

~/music/oldmusic/directorycontainingsubdirectories/*/*
I thought that might be the case....but the funny thing is, I got the

Code:

*/./*
from a reply to someone else's question on another forum, when I Googled for a way to play all subdirectories within a directory without having to make a playlist for Mplayer. It looked wrong to me, but I thought maybe i was just missing something, as I'm no 'puter geek!

And so, in like manner, if I were to do

Code:

mplayer -shuffle ~/music/*/*/*/*
It would play everything in ~/music?

Would it play everything at every "level"?

i.e. would it play both:

Code:

~/music/somecrappysong.mp3
AND
Code:

~/music/oldmusic/blahblahblah/crustyoldie.mp3
???

Thanks, everyone!

grail 10-19-2014 09:20 AM

No ... it will only play all the files at the end of the chain, ie all those that exist in the directory after the last /

Sumguy 10-19-2014 09:34 AM

Quote:

Originally Posted by grail (Post 5256021)
No ... it will only play all the files at the end of the chain, ie all those that exist in the directory after the last /

Ah, kinda what I suspected. Just for reference, would there be any way to specify a path which would allow it to play files contained at different levels?

suicidaleggroll 10-19-2014 09:35 AM

As grail said, the "/" forces it to only match directories. So if there are any files 2 levels down, they will be skipped and it will ONLY pass into directories, and those directories' subdirectories, and those subdirectories' files.

If you want to match any mp3 files at any level, you're better off using find.
Code:

find ~/music -iname "*.mp3"
I imagine you could then pass the list into mplayer with xargs
Code:

find ~/music -iname "*.mp3" | xargs mplayer -shuffle

Sumguy 10-19-2014 10:16 AM

Quote:

Originally Posted by suicidaleggroll (Post 5256027)
As grail said, the "/" forces it to only match directories. So if there are any files 2 levels down, they will be skipped and it will ONLY pass into directories, and those directories' subdirectories, and those subdirectories' files.

If you want to match any mp3 files at any level, you're better off using find.
Code:

find ~/music -iname "*.mp3"
I imagine you could then pass the list into mplayer with xargs
Code:

find ~/music -iname "*.mp3" | xargs mplayer -shuffle

Interesting!

Just running the find command as youy specified, indeed finds all of the mp3's at any level under /music [This forum really needs a thumbs-up emoticon!]

But I suspect that piping it to mplayer requires a little more tweaking- trying it as specified, it had a few problems: It would attempt to play some files, but then say "file not found"[but it did play others]; the shuffle was not working; and when I'd hit enter to jump to the next track, it had no effect. Maybe a certain option has to be specified in mplayer?

This is VERY interesting, and very helpful- I have just learned a lot, that will be of great use to me as it pertains to many other scenarios! [Until now, I had never even heard of xargs!]

EDIT: Hmmm....maybe what we need here is something to just specify that the results of find be exported as a list to mplayer? [I'm clueless as to how to acheive that, but it should be easy for you guys!]

rknichols 10-19-2014 10:30 AM

You will run into problems if any of the file or directory names include embedded whitespace characters. Each "word" will be passed as a separate argument, and mplayer won't be able to find a file by that name. A solution for that is to tell find and xargs to use the NUL character as a separator:
Code:

find ~/music -iname "*.mp3" -print0 | xargs -0 mplayer -shuffle
Or, simply let find invoke mplayer directly so that the names don't get re-parsed by xargs:
Code:

find ~/music -iname "*.mp3" -exec mplayer -shuffle {} +

Sumguy 10-19-2014 10:50 AM

Quote:

Originally Posted by rknichols (Post 5256043)
You will run into problems if any of the file or directory names include embedded whitespace characters. Each "word" will be passed as a separate argument, and mplayer won't be able to find a file by that name. A solution for that is to tell find and xargs to use the NUL character as a separator:
Code:

find ~/music -iname "*.mp3" -print0 | xargs -0 mplayer -shuffle
Or, simply let find invoke mplayer directly so that the names don't get re-parsed by xargs:
Code:

find ~/music -iname "*.mp3" -exec mplayer -shuffle {} +

Ooooo! That seems to do it!

One question, for my edification: What does the "{} +" mean?

suicidaleggroll 10-19-2014 11:09 AM

"{}" means "stick the matching filename here".

There are two ways to end -exec in find:

1) "\;" - when you use this format, it will run the command once per matching file
2) "+" - when you use this format, it will run the command just one time, with all matching files

Sumguy 10-19-2014 12:51 PM

Quote:

Originally Posted by suicidaleggroll (Post 5256069)
"{}" means "stick the matching filename here".

There are two ways to end -exec in find:

1) "\;" - when you use this format, it will run the command once per matching file
2) "+" - when you use this format, it will run the command just one time, with all matching files

Thank you!!!

I'm intending to learn some basic scripting over the winter, as time permits, but so far, just what I've learned in this thread will help me do/simplify some other tasks.

Would the above apply to the "mv" command as well?

I mean, could I do this:

Code:

find `/<location> -iname "*.JPEG" -exec mv /<newlocation> *.jpg \
To move a file from one location to another, while changing it's .JPEG suffix to .jpg? Or maybe just pipe it, like:


Code:

find `/<location> -iname "*.JPEG" | mv /<newlocation> *.jpg \
(Sorry if I'm being a pain and an info glutton, but this is the best and fastest way for me to learn this stuff, as it is specific to what I need to do, and thus I will actually use it- and once I actually do it a few times, I'll remember it- unlike watching hours of youtube tutorials and then forgetting 99% of it after 15 minutes! :D)

EDIT: No, I know something is wrong there, regardless- as I somehow need to specify in the first part of mv where the file is coming from, not just the new location.....

Edit The 2nd: Ah-HA! Maybe:


Code:

find `/<location> -iname "*.JPEG" | mv {} /<newlocation> *.jpg \
Huh? HUH?! :)

rknichols 10-19-2014 01:25 PM

Quote:

Originally Posted by Sumguy (Post 5256109)
Edit The 2nd: Ah-HA! Maybe:


Code:

find `/<location> -iname "*.JPEG" -exec mv {} /<newlocation> *.jpg \

Close, but besides that stray back quote (that I assume is a typo) there are two problems. First, you don't want that final "*.jpg" on the mv command. It's getting its source arguments pasted in by find in place of the "{}" marker, and mv can't do name transformations like the rename command does. Second, you're missing the final semicolon. So, this would work:
Code:

find /<location> -iname "*.JPEG" -exec mv {} /<newlocation> \;
but if there is a large number of files it's inefficient because it invokes mv separately for each file. Trying to use "+" to move multiple files in one invocation runs into the problem that find insists on "{}" coming last in the argument list. The mv command has a "-t" (--target-directory) option to get around that as well:
Code:

find /<location> -iname "*.JPEG" -exec mv -t /<newlocation> {} +
To rename the ".JPEG" files to ".jpg", run the rename command separately:
Code:

rename .JPEG .jpg /<newlocation>/*.JPEG

Sumguy 10-19-2014 11:18 PM

Excellent! Thank you so much, rknichos! This is great info.

And thanks to all who have responded. I've learned far more than just the meaning of " */./* " !!!


All times are GMT -5. The time now is 11:08 PM.