Tag Info

Hot answers tagged

6

To be maximally portable and work when filenames may include spaces or other characters from IFS, and on systems where find does not handle {} inside quotes, use find -exec in combination with sh and ordinary parameter passing: find DIRECTORY -type f -exec sh -c 'grep -lFe "$(basename "$1")" "$1"' sh {} ';' find DIRECTORY -type f enumerates all the ...


6

Use command date to generate current day with proper output format, and append that string to file name in the following fashion: filename=StaticData_Sets_$(date +"%Y%m%d") find . -name "$filename*.txt"


5

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


4

Here's a quick Python program that should output your desired schema, using recursion. Should work in both Python 2 and 3 (although I only tested on 2). The first argument is the directory to descend into, or by default, the script will use the current directory. #!/usr/bin/env python import os import errno def path_hierarchy(path): hierarchy = { ...


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


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


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


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


3

You're using the wrong tool. wc will count lines of input but since you're using sed -i, there are no lines printed so nothing for wc to count. Even without it, the sed command would have printed all lines of the file so it still would not have worked correctly. Here's a different approach: Use perl instead find . -name \*.php \ -exec perl -i -lpe ...


3

You have most of it already. You just need to change your -exec to a -printf find /var/warehouse/* -type f \( -name "*.avi" -o -name "*.mkv" -o -name "*.flv" -o -name "*.mp4" \) -printf "%f\n" %f will print the name of the file that was found, ignoring the path to it. You may also want to consider changing your -name to -iname (case insensitive match) so ...


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.


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


2

Thanks to goldilocks for help, using -maxdepth solved my issues. The problem was that I was giving -maxdepth after -path. The following syntax works as expected: find . -maxdepth 1 -path \*/pages/*/index.css


2

find's -delete flag works similar to rmdir when deleting directories. If the directory isn't empty when it's reached it can't be deleted. You need to empty the directory first. Since you are specifying -type d, find won't do that for you. You can solve this by doing two passes: first delete everything within dirs named __pycache__, then delete all dirs ...


2

Like geedoubleya said, you are missing a '\' at the end of your find commands. So change these: find . -type f -exec chmod 644 {} ; find . -type d -exec chmod 755 {} ; To these: find . -type f -exec chmod 644 {} \; find . -type d -exec chmod 755 {} \; You need to escape the semicolon because "find" and its subshell created with -exec interpret that ...


2

You could use find with a type argument. find . -maxdepth 1 -type f -exec rm -f {} \; You can do a dry run by removing the -exex rm -f {} \; portion to see the files that would be deleted.


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


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


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

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


2

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


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

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

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]*'


2

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


2

Try: find . -type f -name "*.txt" -printf '%h\n' | sort | uniq This works as follows: find . -type f -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


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

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



Only top voted, non community-wiki answers of a minimum length are eligible