Tag Info

New answers tagged

1

With GNU find and bash find . -type d -exec bash -c \ $'for f; do find \"$f\" -maxdepth 1 -type f -name \'*.txt\' -printf \'%h\\n\' -quit; done'\ _ {} +


2

A problem can be that directory names can contain newlines, therefore the output from find should be NUL terminated. In order to have readable output pipe the result of sort through tr: find . -name "*.txt" -printf '%h\0' | sort -zu | tr '\0' '\n' Any newline in a directory name can probably be determined by looking at the next line, if it starts with ./ ...


2

POSIX compatible code which should work for any filename: find . -name '*.txt' -printf '%h\0' | tr '\0\n' '\n\0' | sort -u | tr '\0\n' '\n\0'


2

Try: find . -name *.txt -printf '%h\n' | sort | uniq This works as follows: find . name *.txt -printf '%h\n' - find all files that end in *.txt and print it's directory (%h) followed by a newline. | sort - sort the directories | uniq - remove duplicates


0

This should work for you: find . -iname "*.txt" -exec dirname {} \; | sort | uniq The find + exec will get the directory names of all the *.txt files, sort|uniq will get you the unique such directories.


4

You missing ; character to terminate primary expression (See POSIX find): find . -type f -name \*.out -exec basename {} ';' The reason you must escape, or quote ; because it's your shell list separator. You must make your shell treat it literally. \;, ';' or ";" all work well. But this solution will call basename for each file found, make it slow. If ...


2

you left \; find . -type f -name \*.out -exec basename {} \; you add awk too: find . -type f -name \*.out -print | awk -F "/" '{print $NF}'


3

Your command is missing a semicolon at the end, to terminate the -exec: find . -type f -name \*.out -exec basename {} \; But that command will run quite slowly because it forks an external process and calls basename for each and every match. If your find supports the -printf option, you might want to use that instead: find . -type f -name \*.out -printf ...


0

In bash: # renaming files in the current directory only for f in *.MP3; do mv "$f" "${f%.MP3}.mp3"; done # renaming files in subdirectories as well for f in *{,/*}.mp3; do mv "$f" "${f%.MP3}.mp3"; done


2

With simple -name: find /var/log -name '*.[2-9]' or for any digit: find /var/log -name '*.[[:digit:]]' or if other chars are possible after digit: find /var/log -name '*.[2-9]*'


1

To find the filenames which ends with a number ranges from . [1 to 5]. find /var/log/ -type f -regextype sed -regex ".*\.[1-5]$"


0

The equivalent in BSD or OSX is $ du -ah simpl | sort -dr | head -6


0

You should select which time you need %y modification %w creation %z change or any combination: stat * --printf="%n\t%y %z\n" | grep -vF $(date -d "last Saturday" +%F) | cut -f1 Also choice what infomation you need and compose --printf= line. Or you can use just find command find -maxdepth 1 -type f -daystart \ ! -mtime $[$(date +%d)-$(date -d ...


1

Simpler: find . -maxdepth 1 -printf '%Ta\t%p\n' | grep -v -i '^sat' ref: This answer.


1

A way to do this : $ LANG=C find . -maxdepth 1 -printf '%p %AA\n' | awk '$NF=="Saturday"{next}{$NF=""}1' I assume we don't print files for all Saturdays. This is or not what you expect.


2

It looks like you want to grep on filenames, buf if you do: find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 egrep -vZ 'vvv|iii' the xargs actually presents the list of files coming out of find as argument to egrep. What you should do to handle the NUL terminated input (from -print0) find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 ...


2

In case B: find . -iname *gall* The shell will expand *gall* into a list of all files matching that pattern. Since you only have one file in your current directory matching that pattern, this becomes: find . -iname gallifrey-road-doctors-14437-1366x768.jpg ...so find will search for files matching that exact name. ...


2

Just: find '/shrproj/' -type f -name '*.sas' \ -exec grep -iq 'DB2' {} \; \ -exec grep -ie DSN= -e DATASRC= {} \; \ -ls


0

I'd suggest something along the lines of this (can't do everything in a one-liner) ;-) OLDIFS="$IFS" IFS=$'\n' for i in $(find '/shrproj/' -type f -name '*.sas'); do G1="$(grep -il 'DB2' "$i")" if [ -n "$G1" ]; then G2="$(egrep -Ri 'DSN=|DATASRC=' "$i")" if [ -n "$G2" ]; then echo "$G1" echo "$G2" ls -l "$i" fi fi done IFS="$OLDIFS"


1

The following regular expression should work: -regex ".*/$x[^0-9].*" It contains the number right after the slash followed by a non-number.


2

From the manpage of find: The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command... So, the first part of the find command searches for files greater than 6mb and executes (-exec) split on every found file. For Example, if the found files is ./path/to/file, the command executed ...


0

A solution using bash's array : x=( * ) ((${#x[@]} > 31)) && printf '%s\n' *


1

-delete will perform better because it doesn't have to spawn an external process for each and every matched file. It is possible that you may see -exec rm {} \; often recommended because -delete does not exist in all versions of find. I can't check right now but I'm pretty sure I've used a find without it. Both methods should be "safe". EDIT per comment ...


3

Try: find . -type d -exec bash -c '[[ $(find "{}" -type f | wc -l) -gt 31 ]] && echo {}' \; I'd advise using the -maxdepth restriction on the second find, otherwise you might find some surprising results.


2

This should to it using -gt: for i in $(find . -type d) ; do NUM=$( find $i -type f | wc -l ); if [[ $NUM -gt 31 ]]; then echo "$i $NUM" ; fi done


2

Replace the line: ( find $i -type f | wc -l ) ; With this: FILES=$( find $i -type f | wc -l ); Then you could ask for it: if [ "$FILES" -gt 31 ] ; then


1

With GNU or FreeBSD find: find . -newermt '2014-11-13 9:09' ! -newermt '2014-11-13 9:10' Note that it will report a file last modified at 9:10:00.000000000 and not one at 9:09:00.000000000 but should otherwise be OK for the other 60,000,000,000 nanoseconds in between. With GNU find, assuming file and directory names don't contain newline characters, you ...


0

One additional difference between the two is that shell globs (like /home/user/*) don't usually include "hidden files" (filenames that begin with a dot). On the other hand, find will match all filenames except the special directories '.' and '..' (current and parent directory).


0

Another approach of explaining it: When * is used then the shell knows what the single elements are. The find output is just a long string. The shell does not know what the elements (and their separators) are. Command substitution can be used in a special way with a program that produces quoted output; then the problem would not appear. But in order to make ...


4

This is standard practice for shells. The order of operations is command substitution ($(find .)), then word splitting, then glob expansion (/home/user/*). From the POSIX standard (word splitting = field splitting; glob expansion = pathname expansion): The order of word expansion shall be as follows: Tilde expansion (see Tilde Expansion), ...


4

The shell does things in order. $(find .) is called command substitution. The results of command substitution are subjected: word splitting, pathname expansion quote removal Word splitting is what causes the problem when there are file names with spaces. /home/user/* is pathname expansion. Note that that is second to last on the above list. It is ...


0

find . -readable -size 1033c \! -executable


0

Replace find test/ by find test/.; this is equivalent and should give the same output. Alternatively, instead of using find test/, use find -H test. The option -H tells find to follow symbolic links on the command line, which is what test/ does if test is a symbolic link to a directory. The only difference is that if test is a dangling symlink, find test/ ...


1

I am not sure in high speed but should work too for i in * do { IFS= read -r line1 && IFS= read -r line2 && case $line2 in *some_string*) printf "%s\n" "$i" ;; esac } < "$i" done


5

awk 'FNR==2 {if (/some string/) print FILENAME; nextfile}' ./* Some awks don't have "nextfile".


-1

Change the command to execute to echo: find / -type d -mount -exec echo {} \;


1

You can add the -wholename test with a not (!) to remove the directory. For example: find /mystuff/temp/videos ! -wholename 'mystuff/folder' -type d -exec chmod 777 {} \; From the man page: -wholename pattern File name matches shell pattern pattern. The metacharacters do not treat '/' or '.' specially; so, for example, find . ...


1

Try: find /mystuff/temp/videos -type d ! -name 'folder1' -exec chmod 777 {} + A note that you should not set 777 permission, it's a big hole in security.


3

Find cannot read its path from stdin, you cannot specify - like with many other programs. I recommend that you use GNU parallel to run things in parallel: find . -mindepth 1 -maxdepth 1 -type d -print0 | parallel -0 --jobs 4 \ find {} -name "war" -type d Please note the added -mindepth 1 to the first find. If you don't include that, the current ...


0

use this: find . -maxdepth 1 -type d -print0 | xargs -0 -I {} -P4 find "{}" -name "war" -type d better way is exclude . path: find . -maxdepth 1 -not -path . -type d -print0 | xargs -0 -I "{}" find "{}" -name "war" -type d


0

read -p "SOURCE: " sourcedir read -p "TYPE: " type read -p "TARGET: " targetdir find -L $sourcedir -iname "*.$type" -exec cp -v {} $targetdir \;


3

You can do: find . -exec ./is_dir.py {} \; -o -print It will list everything that is not a directory. Assuming that is_dir.py is executable (chmod +x is_dir.py) and contains something like: #!/usr/bin/env python import sys import os if os.path.isdir(sys.argv[1]): sys.exit(0) sys.exit(1) And if is_dir.py generates output of its own, you can do: ...


3

In Bourne-like shells (except zsh), leaving a variable expansion unquoted in list context is the split+glob operator. In: cond="-name '*.txt'"; echo $cond The content of $cond is first split according to the value of the $IFS special variable. By default, that's on ASCII space, tab and newline characters. So that's split into -name and '*.txt'. Then the ...


1

POSIXly: find / -xdev -type d -exec sh -c 'for d; do ls -lsd "$d"/*; done' sh {} + -xdev has the same affect as -mount but is portable. A note that this will fail on empty directory.


0

That is the usual behaviour of ls when a directory is given as argument. So you have to avoid ls handling directories specially. You must pass file paths to ls, i.e. -type f instead of -type d. If you want to pass directories, too, (no -type f) then you need the option -d for ls.


2

You can get the current date in that format with: date +%Y%m%d so the following command should find today's file and show its size: ls -l StaticData_Sets_$(date +%Y%m%d)*.txt or find . -name "Static_Data_Sets_$(date +%Y%m%d)*.txt" -ls You could sort the output using ls -lt and look at the topmost entry, which should be either today, or yesterday. In ...


0

With zsh: rm -- *(.) removes the regular files only rm -- *(D.) to also include dot-files (hidden ones) rm -- *(D^/) removes all types of files except directories (that include symlinks to directories) rm -- *(D^-/) removes all types of files except directories and symlinks to directories (it would remove symlinks to directories if it can't ...


1

Using bash (and ignoring symlinks): for file in *; do [[ -f $file ]] && rm -- "$file"; done


-1

sudo mkdir a b c d e sudo touch a/1 b/2 c/3 d/4 e/5 e/a e/b ls a b c d e pqr xyz cd a/ ls 1 cd ../e/ ls 5 a b cd /var/warehouse/abc/ find . -type f ! -path "./a*" ! -path "./b*" ./d/4 ./e/a ./e/b ./e/5 ./c/3 sudo find . -type f ! -path "./a*" ! -path "./b*" -exec rm -f {} \;


1

Simple way is to use $ rm ./* Here we are not using recursive delete (-r) and so only the files (except the hidden ones) in the parent directory should get deleted.



Top 50 recent answers are included