LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This 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

Reply
 
Search this Thread
Old 05-15-2011, 12:16 AM   #1
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Rep: Reputation: 15
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.

Kindly provide your inputs....
 
Old 05-15-2011, 12:46 AM   #2
EricTRA
Guru
 
Registered: May 2009
Location: Gibraltar, Gibraltar
Distribution: Fedora 20 with Awesome WM
Posts: 6,805
Blog Entries: 1

Rep: Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290
Hi,

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.

Kind regards,

Eric
 
Old 05-15-2011, 07:56 AM   #3
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713
This will add the ".dir" to directories. I'm not sure how to tell if a directory has a file with a certain name, though.

Code:
find . -type d -exec mv '{}' '{}'.dir ';'
 
Old 05-15-2011, 10:23 AM   #4
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
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.

How shall i go about it??
 
Old 05-15-2011, 10:36 AM   #5
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713
This might work (UNTESTED)

Code:
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

Last edited by MTK358; 05-15-2011 at 10:37 AM.
 
1 members found this post helpful.
Old 05-15-2011, 10:46 AM   #6
EricTRA
Guru
 
Registered: May 2009
Location: Gibraltar, Gibraltar
Distribution: Fedora 20 with Awesome WM
Posts: 6,805
Blog Entries: 1

Rep: Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290
Hi,

If you only want to retain the files with .txt and delete all the others, you might do it with this:
Code:
find /yourdir -type f -not -name '*.txt' -exec rm {} \;
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.

Kind regards,

Eric
 
Old 05-15-2011, 11:01 AM   #7
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Thanks to both of you. It worked.

I was on different track, once the directories were renamed to <orginal_name>.dir , i was trying to use xargs:-

Something like this:-
find . -iname '*dir' | xargs find . -iname '*.txt' | <3rd action Point>

But it wasn't working for me..

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.

Thanks
 
Old 05-15-2011, 11:08 AM   #8
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713
Quote:
Originally Posted by sahil.jammu View Post
*dir
Big mistake.

It should be '*.dir', not '*dir'. Just '*dir' (without the dot) with match things like "gsfgjdfkgldir", which obviously isn't what you want.
 
Old 05-15-2011, 11:12 AM   #9
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713
Quote:
Originally Posted by sahil.jammu View Post
find . -iname '*dir' | xargs find . -iname '*.txt' | <3rd action Point>
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).
 
Old 05-15-2011, 12:25 PM   #10
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Hello MTK358,

Regarding this Script:-

---
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
---

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
 
Old 05-15-2011, 12:32 PM   #11
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713
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.
 
Old 05-15-2011, 12:35 PM   #12
EricTRA
Guru
 
Registered: May 2009
Location: Gibraltar, Gibraltar
Distribution: Fedora 20 with Awesome WM
Posts: 6,805
Blog Entries: 1

Rep: Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290
Quote:
Originally Posted by MTK358 View Post
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.

Kind regards,

Eric
 
2 members found this post helpful.
Old 05-15-2011, 12:50 PM   #13
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713Reputation: 713
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:

Replace this line:

Code:
find . -type d -exec mv '{}' '{}'.dir ';'
with this:

Code:
find . -type d -not -name '*.dir' -exec mv '{}' '{}'.dir ';'

Last edited by MTK358; 05-15-2011 at 04:29 PM.
 
Old 05-15-2011, 12:55 PM   #14
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Thanks Eric and MTK358.

Last few posts were quite informative and useful.


Cheers
Sahil
 
Old 05-15-2011, 12:56 PM   #15
EricTRA
Guru
 
Registered: May 2009
Location: Gibraltar, Gibraltar
Distribution: Fedora 20 with Awesome WM
Posts: 6,805
Blog Entries: 1

Rep: Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290
Hi,

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?

Kind regards,

Eric

Last edited by EricTRA; 05-15-2011 at 01:04 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] sed and rename text in file cober Programming 2 02-10-2011 03:30 PM
How to rename a File System in Solaris 9 solarisnewbie Solaris / OpenSolaris 3 02-06-2009 08:34 AM
Directory Traverse & Rename Script fsckin Programming 3 10-05-2008 01:43 AM
bash: make rename script traverse directories morrolan Programming 2 11-08-2006 10:52 AM
Bash script to traverse directory tree and rename files intramaweb Programming 3 10-08-2006 12:51 PM


All times are GMT -5. The time now is 03:26 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration