Tag Info

New answers tagged

2

-exec indeed can be used as a predicate. find(1): Execute command; true if 0 status is returned. So this example would be: find . -type f -exec sh -c 'file "$0" | grep -q Matroska' '{}' ';' -and -delete Obviously, instead of -delete there can be -ls or -print0 or more predicates.


3

POSIXly: find /test/. ! -name . -type d -mtime +0 -exec rm -rf {} \; -prune (we use -prune for the directories that we successfully remove so that find doesn't complain that they're suddenly gone). In any case, note that the modification time (as checked by -mtime above) of a directory file only reflects the last time an entry was added, removed or ...


0

find /test -type d -mtime +1| egrep -v '^/test$'|xargs -I{} rm -rf {}


0

touch -t 201508260000 dummyfile find /path/to/files -type f ! -newer dummyfile -delete Timestamp format yyyyMMddhhmm The first line creates a file which was last modified on the 26th August 2015. The second line finds all files in /path/to/file which has a date not newer than the dummyfile, and then deletes them. If you want to double check it is working ...


1

Well, the -mmin primary is a GNUism that is most likely not supported on AIX as it is a silly expansion compared to what the BSD people and I used as extension in the 1980s already. Given the fact that sfind compiles fine on AIX, I recommend: sfind . -mindepth 1 -type d -mtime +24h -exec rm -rf {} + The code is in schilytools at: ...


1

As @meuh said in his comment, you could use /test/* instead of /test. Your command could then look similar to this: find /test/* -type d -mmin +1440 | xargs rm -rf In this case only the subfolders of /test would be removed.


6

find will set its return code to non-zero if it saw an error. So you can do: if ! find ... then echo had an error >&2 fi | while ... (I'm not sure what you want to do with the find output). To collect all the error messages from find on stderr (file descriptor 2) you can redirect 2 to a file. Eg: if ! find ... 2>/tmp/errors then ...


3

You don't need .* with find and the space between . and * is often a mistake, since the * will expand to every entry in the current directory, and tell find to use that as a path to search. That's also why your other find sometimes shows files twice. If the j$(pwd) actually matches a file it will also be matched by *. So your delete one will probably do ...


0

I recommend to use star as star comes with a builtin find. This enables features that cannot be achieved with a separate find command.


0

With zsh: print -rl mydir/**/*.A(.e_'REPLY=$REPLY:r; [[ -f $REPLY.B ]]'_) :r removes the extension, so if the content of $REPLY was mydir/somedir/somefile.A after running REPLY=$REPLY:r its content becomes mydir/somedir/somefile; the rest is similar to this answer.


0

/*/aaa does not match /aaa and this is the reason why find cannot find /aaa/bbb If you don't like to start the find at / and if you don't have a recent find like the portable sfind that supports -path you need a better manual start list.


1

Use the -path option for this case: find / -type d -path '*/aaa/bbb' From the man page for find: File name matches shell pattern pattern. The metacharacters do not treat / or . specially; so, for example, find . -path "./sr*sc" will print an entry for a directory called `./src/misc' (if one exists). Cross-Platform Compatibility Edit: I ...


3

The simplest method is to use awk's output redirection. Awk output redirection is very easy to use in simple cases: the file is opened the first time a redirection is used, and subsequent redirections to the same file name use the existing file descriptor. If you wanted to add a suffix to the file name, it would be as easy as find -type f -iname "*.txt" ...


0

The answer from Gilles is correct in that the Windows version of the find command comes before the cygwin version, and so that is being called. Putting Cygwin ahead however will mean that any batch files that use the windows find command will now actually call the cygwin find command, which may not be what you want. The most symbiotic way for both to work, ...


3

You can run bash inside find with -exec option and run file inside shell, e.g.: find . -type f -execdir bash -c 'file "$0" | grep -q Matroska && rm "$0"' {} \;


-1

I came up with: find . -type f -size '+2M' -print | while read i do echo " " > $i done which works.


2

You can do this by a find command: for i in $(find . -type f -size +2097152c);do cat /dev/null > $i;done The find command find . -type f -size +2097152c will find all files of size greater than 2MB (2097152 bytes) The for loop will loop into the list of the files it got in the find command and will clean them out with a cat /dev/null ...


3

I like to answer the direct question first, but do not run this before reading to the end of my answer. The command you are asking for (which may not be what you want) is: find /wherever -type f -name '*.log' -size +4096 -print \ | xargs truncate --size 0 Note that the +4096 means files with more than 4096 512-byte sectors. The problem is that if ...


0

Posixly: find . ! -name . -prune -type f -size +2097152c -exec sh -c ' for f do : > "$f" done ' sh {} + With GNU find or BSD find: find . -maxdepth 1 -type f -size +2M ...


0

You can combine the predicates using -a (for and) or -o (for or). So, you can type find /path -type f -o -type l


5

You can group and use logical operators with find, but you have to escape the parens so you could look for all files and links like find \( -type f -o -type l \) <other filters> so if you wanted all files and links whose name starts with t you could do find \( -type f -o -type l \) -name 't*' You only need the parens if you want to group things ...


1

Try this: find -type f -o -type l


0

I think it is easier to do a logic test before the loop. But this is a hack n' slash into the for-statement: for dir in `! find /etc/aaa -type d -maxdepth 1 2>/dev/null && echo error && exit`; do //your code done //your code This will also suppress the stderr of find.


0

I do not understand why you would want to exit the loop in the middle of it's execution. I do not think it is worth executing the loop if the directory you desire is not present. I think you should do something along the lines of: if [ ! -d /etc/aaa ]; do echo "Error" exit 1 else for files in $(ls /etc/aaa); do # code done # ...


0

You could do something like: if dirs="$(find /etc/aaa -type dir -maxdepth 1 2> /dev/null)"; then for dir in ${dirs}; do # Your code done # Your code else # find failed, generate error fi


1

find Directories -mindepth 4 -type d -print0 | parallel -0 -j0 ./MyScript -d {2} {1} ::: a b c d :::: -


5

The solution that works with any POSIX compatible find is the following: find DIR -type f -perm -0755 ! -perm 0755 ! -perm -04000 ! -perm -02000 -print As previously noted, with GNU find you can collapse the setuid and setgid tests into ! -perm /06000.


3

I'm not sure I understand what you want, but, based on my best guess, find (starting_directory) -type f -perm -755 ! -perm 755 ! -perm /6000 would seem to do it.  -perm /mode means "Any of the permission bits mode are set for the file."  So -perm /6000 should match only files that are SUID or SGID (or both), and ! -perm /6000 should exclude those ...


0

Or do it with a loop: for x in $(find /var/dtpdev/tmp/ -type f -mtime +15); do rm "$x"; done


2

Use this: find -name "* *" -print0 | sort -rz | \ while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done find will search for files and folders with a space in the name. This will be printed (-print0) with nullbytes as delimiters to cope with special filenames too. The sort -rz reverses the file order, so that the deepest ...


0

find $1 -depth -name "* *" -type d -execdir rename 's/ /_/g' "{}" \;


0

separate between filename basename (i.e. last name in the path) and dirname: find $1 -depth -name "* *" -print0 | \ while read -d $'\0' f ; do a="$(dirname "$f")" b="$(basename "$f")" #optional check if the basename changes -> reduces errors in mv command #only needed when using -wholename instead of -name in find, so skippable if [ ...


10

Use this with bash: find $1 -name "* *.xml" -type f -print0 | \ while read -d $'\0' f; do mv -v "$f" "${f// /_}"; done find will search for files with a space in the name. The filenames will be printed with a nullbyte (-print0) as delimiter to also cope with special filenames. Then the read builtin reads the filenames delimited by the nullbyte and ...


8

Using rename find . -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \; or with $1 find "$1" -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \; Using mv find . -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \; or with $1 find "$1" -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \;


6

Here is a portable way: find / -type d -exec test {} = /zones \; -prune -o -type d -print Note that GNU find might be available on an alternate directory depending on the Solaris release you are using (like /usr/sfw/bin/gfind, /usr/gnu/bin/find, ...).


-1

for i in `ls -1`; do echo $i : `ls -1 $i|wc -l`; done


1

As file in $( echo $file | md5 ) will not be interpreted, you need a workaround. One possibility is to simply pipe it into a while loop and read each output - in that case better skip xargs as a whole find ... | while read file ; do cp "$file" "datnew/$( echo "$file" | md5 )" ; done For using it with -print0 replace the null character with a newline ...


0

On SuperUser there is an alternative posted by Sehe: http://superuser.com/questions/297342/rsync-files-newer-than-1-week rsync -RDa0P --files-from=<(find sourcedir/./ -mtime -7 -print0) . user@B:targetdir/


0

The sort command allows to use the null as tabulation character via -t \0 (as well as the -z proposed by Arcege). Therefore: find folder1 folder2 -name "*.txt" -print0 | sort -t \0 | xargs -0 myCommand Using \n as separator produces a better readable intermediate outputs, but as stated by Ole Tangue reply, it will make it harder to handle with xargs. ...


2

This should do it. Where the first column (size) exceeds 10gb, output the second column (directory name) du -sk * | awk '$1 > 10485760 { print $2 }' Or as requested, to show in human readable form, as below. The regular expression ensures column 1 ends in a G (gigabytes) and the substr part strips the final letter from column 1 and looks to see if ...


4

You're showing us the output of find . -maxdepth 1 -mtime -3 -print0 What's the output of find . -maxdepth 1 -mtime -3 -print0 | grep -z loader ?  I don't see any file names containing the word loader in the output that you did show.  If the output from the grep (which is the input to xargs) is nothing, then, naturally, nothing will be copied. Also, ...


2

To make grep print only the file name, pass the -l option. To search for a substring rather than a regular expression, pass the -F option. To search recursively for files whose name matches a certain pattern, use find with the -type f and -name PATTERN primaries. Use -exec to invoke grep. find . -name '*.sas' -type f -exec grep -F -l 'Carhart' {} + If ...


0

If you would prefer not to invoke a subshell for every single file, this refinement of jlliagre's answer does it all with find predicates, as long as there are no ACLs to make it even more complicated. Correctly handling directories that are readable but not searchable is left as an exercise. If you haven't seen the #! thingy before, it means "don't try to ...


5

Here is a POSIX way to prune any non readable directory with find : find . \( -exec sh -c ' if [ ! -r "$1" ] ; then { exit 1 ; } ; else for i in "$1"/* ; do if [ -d "$i" -a ! -r "$i" ]; then exit 1; fi; done; fi ' sh {} \; -o -prune \) -a -print Note that if this is a full Solaris installation, GNU grep is available in /usr/sfw/bin/ggrep.


1

Just filter them out. find . 2>&1 | grep -v "^find: cannot read dir .*: Permission denied$"


1

Using the same ls -CFUd as muru but in zsh, you could try with: setopt nullglob ls --color -CFUd -- *(/) *(*) *(@) *(p) *(=) *(^/*@p=) where (...) are glob-qualifiers matching directories, executables, symlinks, pipes, sockets and respectively everything else.


1

If dirty hacks are welcomed, the following might come close: ls -C --color -F -1 | rev | sort | rev Essentially: rev to get the last character first then sort, which will now use the last character first then rev again to get back the original line This, unfortunately, has single-column output. You can apply column to it to get multi-column output, ...


1

I use this for my case and it works quite well, as I know the directory to look for broken symlinks: find -L $path -maxdepth 1 -type l and my folder does include a link to /usr/share but it doesn't traverse it. Cross-device links and those that are valid for chroots, etc. are still a pitfall but for my use case it's sufficient.


0

With zsh and (.m[-|+]n) glob-qualifiers: print -rl -- *(.m90) will list files modified exactly 90 days ago, print -rl -- *(.m-90) will list files modified in the last 90 days, print -rl -- *(.m-100m+80) will list files modified between 80 and 100 days ago.


0

You could also use the fx operator to filter images based on height/width e.g. identify -format '%[fx:(h>400 && w>400)]\n' image.png will output 1 if the image is bigger than 400x400 and 0 if it's equal or smaller than 400x400... Assuming sane files names (no newlines/spaces/tabs etc) you could use identify to print image names preceded ...



Top 50 recent answers are included