Find

find

The -print argument specifies to print the names (path) of the matching files. When -print
is used '\n' will be the delimiting character for separating each file.

The -print0 argument specifies each matching file name printed with the delimiting
character '\0'. This is useful when a filename contains a space character.

based on name

find /home/xyz -name "*.txt" –print
find . ! -name "*.txt" -print
find /home/xyz -name "*.txt" –print // ignore case

find /home/xyz \( -name ".git" -prune \) -o \( -type f -print \)

The above command prints the name (path) of all the files that are not from the .git directories.

find . \( -name "*.txt" -o -name "*.pdf" \) -print
find . -regex ".*\(\.txt\|\.pdf\)$"

find file name or file path has firefox

find /home/users -path "*firefox*" -print

based on depth

In order to restrict find from descending into the subdirectories from the current directory, the depth can be set as 1

find . -maxdepth 1 -type f -print

find . -mindepth 2 -type f -print

based on file type

Regular file f
Symbolic link l
Directory d
Character special device c
Block device b
Socket s
Fifo p

base on time

Print all the files that were accessed within the last 7 days as follows:

$ find . -type f -atime -7 -print

Print all the files that are having access time exactly 7 days old as follows:

$ find . -type f -atime 7 -print

Print all the files that are having access time older than 7 days as follows:

$ find . -type f -atime +7 -print

Access time (-atime): This is the last timestamp of when the file was accessed by some user
Modification time (-mtime): This is the last timestamp of when the file content was modified
Change time (-ctime): This is the last timestamp of when the metadata for a file

(such as permissions or ownership) was modified

amin, mmin, cmin based on minutes

based on size

find . -type f -size +2k

b – 512 byte blocks
c – bytes
w – two byte words
k – Kilobyte
M – Megabyte
G – Gigabyte

based on user or permission

find . –type f –name "*.php" ! -perm 644 –print
find . -type f -user slynux -print

exec

find . -type f –user root –exec chown xyz {} \;

For each file match, {} will be replaced with the file name in place for –exec. For example, if the find command
finds two files test1.txt and test2.txt with owner slynux, the find command will perform:
chown xyz {} This gets resolved to chown xyz test1.txt and chown xyz test2.txt.

\; is the exec command termination symbol. some system will also allow to use + to terminate the command.

Another usage example is to concatenate all the C program files in a given directory and write
it to a single file all_c_files.txt. We can use find to match all the C files recursively and
use the cat command with the -exec flag as follows:

$ find . -type f -name "*.c" -exec cat {} \;>all_c_files.txt

interesting, we used the > operator instead of » (append) because the entire output from the find command
is a single data stream (stdin).

find . -type f -name "*.txt" -exec printf "Text file: %s\n" {} \;

xargs

background

pipe is used to redirect stdout (standard output) of a command to stdin (standard input) of another command.

however, some of the commands/applications accept data as command-line arguments rather than a data
stream through stdin (standard input). In that case, we cannot use pipes to supply data through command-line arguments.

xargs is a command that is very helpful in handling standard input data to the command-line argument conversions

  • Converting multiple lines of input to a single line output:
  • Converting single line into multiple line output. xargs -n 3
  • convert using specific delimiter

echo "splitXsplitXsplitXsplit" | xargs -d X -n 2
split split
split split

  • support both dynamic and constant parameters. When –I is used with xargs, it will execute as one command execution per argument.

cat args.txt | xargs -I {} ./cecho.sh -p {} -l
will generate :
./cecho.sh –p arg1 –l
./cecho.sh –p arg2 –l
./cecho.sh –p arg3 –l

use print0

find . -type f -name "*.txt" -print0 | xargs -0 rm -f

should not use :

find . -type f -name "*.txt" -print | xargs rm -f

because if the output file of find contains space (' '), it will be split into two files and very dangerous.

-print0 along with find to produce an output with delimited character null ('\0') and
xargs -0 interprets that the delimiting character is \0.

Counting number of lines of C code in a source code directory

find source_code_dir_path -type f -name "*.c" -print0 | xargs -0 wc -l

use while loop instead

cat files.txt | ( while read arg; do cat $arg; done )

  1. Equivalent to cat files.txt | xargs -I {} cat {}

difference between exec and xargs

find . -name H* -exec ls -l {} \; executes the command ls -l on each individual file.

find . -name H* | xargs ls -l constructs an argument list from the output of the find commend and passes it to ls.

consider if the ouput of the find command produced:

H1
H2
H3

the first command would execute
ls -l H1
ls -l H2
ls -l H3

but the second would execute

ls -l H1 H2 H3

the second is faster because xargs will collect file names and execute a command with as long as a length as possible.
Often this will be just a single command.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License