Traverse the file system and Rename (xargs or sed?)
Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
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.
Traverse the file system and Rename (xargs or sed?)
Hello Everyone,
I need your inputs on performing some operations:-
a. Traverse from top Level directory, find all the directories
b. Rename all these directories to <original name>.dir
c. Once the renaming is done - search from top level and retain only those directories which has .txt content in them.
d. Delete rest all.....
Can i use xargs here to perform operation a and b , or will sed will be useful.
You could use find with -exec or pipe the output from find to xargs for example. You can even loop through the directory and use a loop to process the filenames with sed. Try them all out and see if they work for you. If you tried and encountered errors, please post the command you used and the errors you get.
Thanks Eric and find "MTK358" . Now with the execution of :- find . -type d -exec mv '{}' '{}'.dir ';'
All my directories are renamed to <original name>.dir
Now with this new naming structure, i am interested in doing find from top level (recursive), look into all the directories/sub-directories (check for the extention .txt) retain the directories which have .txt in them and delete rest all.
find . -type d -exec mv '{}' '{}'.dir ';'
function contains_txt_files
{
for file in "$1"/*
do
echo "$file" | grep '\.txt$' &> /dev/null
if [ $? '=' 0 ]
then
return 0
fi
done
return 1
}
find . -type d | while read d
do
contains_txt_files "$d"
if [ $? '!=' 0 ]
then
rm -r "$d"
fi
done
That will find you all the files that don't have .txt and delete them, leaving you with only files with .txt. Test before executing the actual rm with for example ls. If you also want to delete the directories not containing .txt files then you'll have to use a solution such as pointed out by MTK358.
Plz correct me on use of xargs ( i can use find twice in same go right? )
find . -iname '*dir' | xargs find . -iname '*.txt' //this command wasn't working for me
Error:-
find: paths must precede expression
Usage: find [path...] [expression]
Solution provided by you solved the problem, but if you can provide some info related to my error, it will be a good learning.
See the "." after "find"? That specifies the directory to search. "." means the current directory. Also, "xargs" will add all the directories as arguments, but "find" can only search one directory (it's wrong to specify many).
function contains_txt_files
{
for file in "$1"/*
do
echo "$file" | grep '\.txt$' &> /dev/null
if [ $? '=' 0 ]
then
return 0
fi
done
return 1
}
find . -type d | while read d
do
contains_txt_files "$d"
if [ $? '!=' 0 ]
then
rm -r "$d"
fi
done
---
There is one thing, every-time i run this, it adds .dir as extension to the directory name, if we execute twice name becomes:-
dir_name.dir.dir . How shall we go about it - so that name remains only .dir
I can't find a find option that matches only if a regex or wildcard does not match. I'm not sure how to do this.
Hi,
Have a look at post #6 where I use the -not to find all files that don't match the -name. If I'm not mistaken you can also use it in combination with -regex since it 'reverses' what you're looking for.
I didn't know about "-not", it was very far down in the man page in a place I didn't look. I thought that if there was such a thing, it would be in the "TESTS" section. So:
The man page for find is indeed pretty big. Your command would only leave OP with one problem, the one he stated in #10
Quote:
There is one thing, every-time i run this, it adds .dir as extension to the directory name, if we execute twice name becomes:-
dir_name.dir.dir . How shall we go about it - so that name remains only .dir
meaning that if you run the command a second time a second .dir gets added which is not what he wants. I'm trying to figure out how to overcome that but haven't found a solution yet. Any ideas?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.