LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Recursively clear files (https://www.linuxquestions.org/questions/programming-9/recursively-clear-files-4175423532/)

carlosmp 08-23-2012 12:05 AM

Recursively clear files
 
Hi,

I was trying to find a simple way of starting in a directory and recursively clearing every file. Not deleting the file, but clearing it's contents. Working on some projects, and need to clear/reset log files. I was trying th efind command, but couldn't get it to execute the command i needed. If i'm in the directory, this works, but I need to go down into the subdirecotries and do the same for all files found.

Code:

NODELOGFILES='$NODELOGS/test/*'
for f in $NODELOGFILES
do
        > $f
done

I was also trying this
Code:

find ./ -name '*' -type f -execdir "> '{}'" \; -print
But get a bunch of lines like this:
Code:

find: `> \'./sar22\'': No such file or directory
find: `> \'./sa14\'': No such file or directory
find: `> \'./sa20\'': No such file or directory
find: `> \'./sar21\'': No such file or directory

Any ideas?

Thanks,

Carlos.

etech3 08-23-2012 12:32 AM

Did you try rm -rf * in the directory you want?

BE carefull!

Wim Sturkenboom 08-23-2012 12:51 AM

The error message shows that it's looking for e.g. './sar22' (including the quotes).

What if you change it to the below? Not tested, so it might totally not work!

Code:

find ./ -name "*" -type f -execdir "> {}" \; -print

Wim Sturkenboom 08-23-2012 07:22 AM

OK,

Some time to test it and it did not work

Below does work to delete and recreate the files

Code:

find ./ -name "*" -type f -execdir rm {} \; -execdir touch {} \;-print

NevemTeve 08-23-2012 07:42 AM

eg:
Code:

find ... -exec cp /dev/null {} \;

414N 08-23-2012 07:50 AM

Uhm, couldn't you use logrotate?
Also, specifying "*" as name to search is the same as not specifying it, so you can remove the -name directive.

kevinbenko 08-23-2012 07:51 AM

Try using the
-depth
command under find

carlosmp 08-23-2012 07:56 AM

Quote:

Originally Posted by NevemTeve (Post 4762061)
eg:
Code:

find ... -exec cp /dev/null {} \;

Would this keep the file permissions intact? This command is being executed from an openvz host on a template (that is off/stopped), so I don't know what effect this would have on permissions.

Thanks,
Carlos.

carlosmp 08-23-2012 07:58 AM

Quote:

Originally Posted by 414N (Post 4762073)
Uhm, couldn't you use logrotate?
Also, specifying "*" as name to search is the same as not specifying it, so you can remove the -name directive.

Trying to remove/reset the logs, so logrotate won't get that done. Already deleting the logrotated logs.

Thanks,
Carlos

carlosmp 08-23-2012 07:59 AM

Quote:

Originally Posted by etech3 (Post 4761759)
Did you try rm -rf * in the directory you want?

BE carefull!

Trying not to use that as I want to keep the log files with owner/perm in tact. Simply want to empty their contents.

Thanks,
Carlos.

414N 08-23-2012 08:36 AM

If file permissions are your concern, you could try to "cat /dev/null" inside your files, instead of using cp.

theNbomr 08-23-2012 09:02 AM

If you want to empty an existing file, but preserve the file's permission state and ownership, this should work
Code:

echo -ne > theFile
--- rod.

NevemTeve 08-23-2012 09:10 AM

When in find, redirection is a bit tricky:

Code:

bad:    find ... -exec echo -n >{} \;
good:  find ... -exec sh -c 'echo -n >{}' \;
better: find ... -exec cp /dev/null {} \;


David the H. 08-23-2012 04:11 PM

find is not a shell, so its -exec option cannot directly execute shell syntax and functions. That's why the redirections don't work.

You can do it by launching a separate shell for the command, as explained in this link.

How do I invoke a shell command from a non-shell application?
http://mywiki.wooledge.org/BashFAQ/012

Another way to do it is to process the list with a while loop. Use null separators to be completely safe.

Code:

while IFS='' read -r -d '' fname; do

        >"$fname"

done < <( find ./ -name '*' -type f -print0 )

(The above example depends on bash's process substitution, but it should also be safe to feed the loop through a pipe in this case.)


Here are a few more BashFAQ entries that may relate to this topic:

How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?
http://mywiki.wooledge.org/BashFAQ/001

How can I find and deal with file names containing newlines, spaces or both?
http://mywiki.wooledge.org/BashFAQ/020


I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?
http://mywiki.wooledge.org/BashFAQ/024

How do I use 'find'? I can't understand the man page at all!
http://mywiki.wooledge.org/BashFAQ/075


All times are GMT -5. The time now is 07:09 PM.