Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum. |
| 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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
|
07-30-2011, 08:55 PM
|
#16
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,325
|
Could you explain why you feel the brackets are necessary?
|
|
|
|
|
Click here to see the post LQ members have rated as the most helpful post in this thread.
|
07-30-2011, 10:23 PM
|
#17
|
|
Member
Registered: Aug 2009
Distribution: linux
Posts: 527
Original Poster
Rep:
|
Sure,
I seem to remember reading somehting about the way that bash interpets a line. I guess a way of telling bash to read the brackets as part of the commands rather than to enclose another command. er, thats why.
|
|
|
|
07-30-2011, 11:24 PM
|
#18
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,589
|
If you have bash version 4 or higher, then here's a solution that doesn't require find or any other outside tool. It should also work fine with any unusual filename characters, as it relies only on simple shell globbing.
Code:
#!/bin/bash
shopt -s dotglob globstar
files=( ./** )
for file in "${files[@]}" ; do
path="${file%/*}"
name="${file##*/}"
if [[ ! -f $file || ! $name == .* ]] ; then
echo "skipping $file"
continue
else
mv "$file" "$path/${name#.}"
fi
done
exit 0
|
|
|
1 members found this post helpful.
|
07-31-2011, 12:37 AM
|
#19
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,589
|
Quote:
Originally Posted by mrmnemo
Sure,
I seem to remember reading somehting about the way that bash interpets a line. I guess a way of telling bash to read the brackets as part of the commands rather than to enclose another command. er, thats why.
|
Except that grail's question was about why you want to do this in the first place. Parentheses in find are only needed to group expressions together to enforce precedence. In this case it appears you simply want both tests to be evaluated equally, so they are unnecessary. Just use...
Code:
find /media/music/ -depth -name "*.m4a" -o -name "*.wma
But to answer your actual question, $(..) is a subshell. Simply treat everything inside it as if it were on a separate line.
Code:
for f in $( find /media/music/ -depth \( -name "*.m4a" -o -name "*.wma \) )
Also note that $((..)) is a separate operator that expands arithmetical expressions.
Finally, it may have been mentioned before, but a for loop is not recommended when the input is from a command that generates filenames or other strings that can include spaces. This is because for reads each word as a separate input, and can't distinguish lexical whitespace from syntactical whitespace (at least not without futzing about with IFS).
Use a while+read loop instead, with process substitution for input. Since read works on a per-line basis, rather than per-word, each line from find will be safely accepted as the complete filename that it is (barring the unlikely possibility of encountering a filename that itself contains a newline character).
Code:
while read f ; do
your commands
done < <( find /media/music/ -depth -name "*.m4a" -o -name "*.wma" )
Last edited by David the H.; 07-31-2011 at 12:42 AM.
Reason: fixd a cupla typos
|
|
|
1 members found this post helpful.
|
07-31-2011, 11:02 PM
|
#20
|
|
Member
Registered: Aug 2009
Distribution: linux
Posts: 527
Original Poster
Rep:
|
Quote:
Originally Posted by David the H.
Except that grail's question was about why you want to do this in the first place. Parentheses in find are only needed to group expressions together to enforce precedence. In this case it appears you simply want both tests to be evaluated equally, so they are unnecessary. Just use...
Code:
find /media/music/ -depth -name "*.m4a" -o -name "*.wma
But to answer your actual question, $(..) is a subshell. Simply treat everything inside it as if it were on a separate line.
Code:
for f in $( find /media/music/ -depth \( -name "*.m4a" -o -name "*.wma \) )
Also note that $((..)) is a separate operator that expands arithmetical expressions.
Finally, it may have been mentioned before, but a for loop is not recommended when the input is from a command that generates filenames or other strings that can include spaces. This is because for reads each word as a separate input, and can't distinguish lexical whitespace from syntactical whitespace (at least not without futzing about with IFS).
Use a while+read loop instead, with process substitution for input. Since read works on a per-line basis, rather than per-word, each line from find will be safely accepted as the complete filename that it is (barring the unlikely possibility of encountering a filename that itself contains a newline character).
Code:
while read f ; do
your commands
done < <( find /media/music/ -depth -name "*.m4a" -o -name "*.wma" )
|
Wow, thanks you so much. That makes things a lil easier for me to wrap my head around. Could you point me to a book that would be linear in how it goes through bash? I have looked at the bash cook book and it leaves me spun around a little bit. Nominal Animal posted the wiki link for gaining a better grasp of regex ( thanks). Any ways, thanks guys. I have a new job which I will be using bash much more. This is all very helpful.
Ollie
|
|
|
|
07-31-2011, 11:46 PM
|
#21
|
|
Guru
Registered: Aug 2004
Location: Brisbane
Distribution: Centos 6.4, Centos 5.9
Posts: 15,021
|
|
|
|
1 members found this post helpful.
|
08-01-2011, 10:02 AM
|
#23
|
|
Member
Registered: Aug 2009
Distribution: linux
Posts: 527
Original Poster
Rep:
|
@chrism01 and David the H : bookmarked and scanned real fast. Thanks for taking the time to post that guys.
|
|
|
|
08-01-2011, 07:03 PM
|
#24
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,325
|
Quote:
|
Speaking of which, I need to retract something from my last post. After writing it, I came across their find tutorial, and it seems that parenthetical grouping can be more important than I had thought (see section 10).
|
Don't beat yourself up too hard on this one David as the current example given would not have fallen prey to the issue
mentioned here. In saying that, thanks for the find as I did not know that detail before 
|
|
|
|
08-02-2011, 07:03 AM
|
#25
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,589
|
Nah, I'm not "beating myself up" over it. There's always something new to learn, after all, and that sometimes means unlearning wrong stuff too.
I'm mostly just keeping myself honest, and trying to avoid giving bad advice. While the specific example above isn't affected, it would only take a small modification, such as adding an -exec command, to make it vitally important.
|
|
|
|
08-02-2011, 05:40 PM
|
#26
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,325
|
True enough 
|
|
|
|
09-17-2012, 05:20 AM
|
#27
|
|
LQ Newbie
Registered: Sep 2012
Posts: 1
Rep: 
|
I wasn't able to get any of these previous resolutions to work in CentOS.
With a little digging I came to this conclusion:
find ./ -depth -name '.*' -exec bash -c 'mv {} $(echo {} | cut -c 4-)' \;
It might be a little hacky but it successfully renames hidden files and folders within your current directory to not be hidden(unfortunately it doesn't currently work recursively).
|
|
|
|
| Thread Tools |
Search this 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
HTML code is Off
|
|
|
All times are GMT -5. The time now is 03:41 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|