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.... |
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 |
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 ';' |
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?? |
This might work (UNTESTED)
Code:
find . -type d -exec mv '{}' '{}'.dir ';' |
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 {} \; Kind regards, Eric |
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 |
Quote:
It should be '*.dir', not '*dir'. Just '*dir' (without the dot) with match things like "gsfgjdfkgldir", which obviously isn't what you want. |
Quote:
|
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 |
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.
|
Quote:
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 |
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 ';' Code:
find . -type d -not -name '*.dir' -exec mv '{}' '{}'.dir ';' |
Thanks Eric and MTK358.
Last few posts were quite informative and useful. Cheers Sahil |
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:
Kind regards, Eric |
Quote:
I already solved that: http://www.linuxquestions.org/questi...4/#post4357066 |
Hi,
Yes, I've noticed that but that wouldn't work if it were the first run. Say OP is running his tests in a testing environment to build a solution for his problem. After the first run .dir gets added, on the second run and the ones thereafter, if he does change the command between runs, he will not get .dir.dir and so on. But what if he wants to run this as a one command solution on another machine? Most likely OP just runs your commands to clean up his system so this doesn't apply but just thought it worth mentioning for completeness. Kind regards, Eric |
Quote:
|
Hi,
Sorry, didn't notice you've added the -not option. My brain is on Sunday mode. Should work correctly. Kind regards, Eric |
Hello Guys,
Came across another scenario, i'm struck at a point, Need your inputs to proceed further:- ------ 1. Traverse entire file system, look for directories which has .git directory in it 2. Rename the immediate parent directory to <orignal_name.git> 3. Traverse this new file structure and look for all directories with <original_name>.git 4. cd to that directory and remove its contents 5. once everything inside the directory is deleted, create a file ------ Code:- Step 1:- find * -type d -iname '.git' Step 2:- function rename_git_parent { for file in "$1"/* do cd .. | $(pwd) -exec mv '{}' '{}'.git ';' done return 1 } //i am not too sure if its the right way of doing it, or shall i use dirname... How shall i go about step2 and ownwards... Appreciate the help. Thanks. Regards Sahil |
All times are GMT -5. The time now is 02:53 AM. |