文章目录
find命令
Linux下find命令在目录结构中搜索文件,并执行指定的操作。
命令格式
find [-H] [-L] [-P] [-Olever] [-D help|tree|search|stat|rates|opt|exec|ok] [path...] [expression]
默认path为当前目录,默认expression为-print;所以,在写命令的时候可以不指定path和-print
命令功能
用于在文件树种查找文件,并作出相应的处理
命令参数
path:find命令所查找的目录路径。默认.当前目录。
expression:
-print:find命令将匹配的文件输出到标准输出,默认自带当前expression。
-print0,指定输出的文件列表以null分隔
-exec:find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' { } \;,注意{ }和\;之间的空格。
-ok:和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
命令选项
-name 按照文件名查找文件。
-iname 按照忽略大小写的文件名查找文件。
-perm 按照文件权限来查找文件。
-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-mtime -n +n 按照文件的更改时间来查找文件, -n表示文件更改时间距现在n天以内,+n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-newer file1!file2 查找更改时间比文件file1新但比文件file2旧的文件。
-type 查找某一类型的文件,诸如:
b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-mount:在查找文件时不跨越文件系统mount点。
-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。
另外,下面三个的区别:
-amin n 查找系统中最后N分钟访问的文件
-atime n 查找系统中最后n*24小时访问的文件
-cmin n 查找系统中最后N分钟被改变文件状态的文件
-ctime n 查找系统中最后n*24小时被改变文件状态的文件
-mmin n 查找系统中最后N分钟被改变文件数据的文件
-mtime n 查找系统中最后n*24小时被改变文件数据的文件
-name
文件名选项
格式:
find . -name "[A-Z]*.log" # 支持表达式
-perm
选项
按照文件的权限来查找,格式
find . -perm 755 -print
-prune
忽略某个目录
**注意:**如果同时使用了-depth
选项,那么-prune
选项就会被find
命令忽略。
expression -prune -o -print
,-prune
就像一个判断语 句,当-prune
发现前面的表达式成立的时候,执行到-prune
之后就会输出一个1相当于1||-print
,如果不成立的话, 会输出一个0,相当于0||-print
。根据短路原理,会决定-print执行还是不执行。
如果希望在dir目录下查找文件,但不希望在dir/dir1目录下查找:
find dir -name "a.log" -path "dir/dir1" -prune -o -print
在dir目录中,查找名称为*.txt和*.log
之外的文件:
find dir \( -name "*.txt" -o -name "*.log" \) -prune -o -print
find dir -name "*.txt" -o -name "*.log"
和一串表达式执行成功,则-prune
返回1,否则返回0
-o或者-a
或和与
-a
就是逻辑判断中的and
-o
就是逻辑判断中的or
如果相匹配多个条件中的一个,可采用or条件操作:
find . \( -name “*.txt” -o -name “*.pdf” \) -print
注意:\( 内容 \) 内容与括号之间必须有空格,否则会提示有错误
使用实例
-
查找48小时内修改过的文件
find atime -2
-
根据文件名称的关键字查找
find . -name "*.log"
-
按照目录或文件的权限来查找文件
find . -perm 777
-
按照文件类型来查找
find . -type f -name "*.log"
-
查询当前路径下的所有目录,并排序
find . -type d | sort
-
查找当前目录大于1K的文件
find . -size +1000c -print
find命令之exec/ok使用
概述
find是我们很常用的一个Linux命令,但是我们一般查找出来的并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了。
-exec参数后面跟的是command命令,它的终止是以;为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。
{} 花括号代表前面find查找出来的文件名,{}前后必须有空格。
ok命令和exec命令一样,只是在执行command之前进行提示。
使用实例
-
ls -l命令放在find命令的-exec选项中
find . -type f -exec ls -l {} \;
-
在目录中查找更改时间在n日以前的文件并删除它
find -type f -mtime +3 -exec rm {} \;
-
在目录中查找更改时间在n日以前的文件并删除它们,在删除之前先给出提示
find . -type f -mtime +5 -ok rm {} \;
-
-exec中使用grep命令
find /etc -name "passwd*" -exec grep "root" {} \;
-
查找文件移动到指定目录
find . -name "*.log" -exec mv {} ../bak/logs \;
-
用exec选项执行cp命令
find . -name "*.log" -exec cp {} test3 \;
find命令之xargs
概述
xargs 是给命令传递参数的一个过滤器,可以将管道或标准输入的数据转换成参数,默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行,不过通过 xargs 的处理,换行将被空格取代。
在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高; 而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
语法
xargs [OPTIONS] [COMMAND [initial-arguments]]
OPTIONS选项
-d
设置分隔符
默认情况下,参数的分割符是空格或者换行符
echo -e "a\tb\tc" | xargs -d "\t" echo # \t设置为参数的分隔符
-p
参数打印出要执行的命令并询问用户是否要执行。
echo 'one two three' | xargs -p touch
-t
参数则是打印出最终要执行的命令,然后直接执行,不需要用户确认。
echo 'one two three' | xargs -t rm
-L
参数,指定每行作为一个命令行参数
由于xargs
默认将空格作为分隔符,所以不太适合处理文件名,因为文件名可能包含空格。
find
命令有一个特别的参数-print0
,指定输出的文件列表以null
分隔。然后,xargs
命令的-0
参数表示用null
当作分隔符。
find . -type f -print0 | xargs -0 rm
当同时将"*.txt"
和*.md
两行作为命令行参数,传给find
命令导致报错。
使用-L
参数,指定每行作为一个命令行参数,就不会报错。
xargs -L 1 find -name
"*.txt"
./foo.txt
./hello.txt
"*.md"
./README.md
-L
参数虽然解决了多行的问题,但是有时用户会在同一行输入多项。
xargs find -name "*.txt" "*.md" find: paths must precede expression: `*.md'
上面的命令将同一行的两项作为命令行参数,导致报错。
-n
参数指定每次将多少项,作为命令行参数。
$ xargs -n 1 find -name
-n
限制参数的数量
默认情况下,传递给命令的参数数量由系统限制决定。-n
选项指定要传递给命令的参数个数。xargs根据需要多次运行指定的命令,直到所有参数都用完为止。
echo "file1 file2 file3"|xargs -n 1 -t touch #-t表示在执行command之前先打印,-n 1每次传一个参数,则需要执行3条命令
-I/-i
运行多个命令
要使用xargs运行多个命令,请使用-I
选项。在-I
后面自定义一个传递参数符号,所有匹配的项都会替换为传递给xargs的参数。
下面例子时xargs运行多条命令:
echo "file1 file2 file3" | xargs -t -I % sh -c 'touch %;ls -l %';
ls | xargs -I {} sh -c ' ls {} && echo ":" && cat {}'
**
sh -c
**命令,后面有专门的解释。就是从字符串中加载命令脚本。
-i
和-I
的区别:-i
默认使用{}
作为替换字符,相当于-I {}
以下两条语句等价:
ls | xargs -I {} sh -c ' ls {} && echo ":" && cat {}'
ls | xargs -i sh -c ' ls {} && echo ":" && cat {}'
-a
从文件中读取参数
xargs命令还可以从文件读取条目,而不是从标准输入读取条目。使用-a选项,后跟文件名。
读取一个ip.txt中的所有ip,并进行ping
xargs -a ip.txt -L 1 ping -c 2 # 从ip.txt读取ip,每一行执行一个ping命令,ping2次
bash -c参数的使用
使用方式
bash -c "string"
官方解释:
If the
-c
option is present, then commands are read fromstring
. If there are arguments after the string,they are assigned to the positional parameters, starting with $0.
通过官方解释,可知道,参数-c
就是从一个字符串中加载shell脚本。
所以,我们可以把多个脚本命令写到一个字符传中执行:
bash -c 'echo "hello world";ls -l;touch a.txt'
自定义一个脚本test.sh
,里面命令如下:
echo $0
echo $1
echo $2
echo $3
修改test.sh的权限,执行如下命令:
$ bash -c "./test.sh hello world"
./test.sh
hello
world
./test.sh #就是$0参数的输出
hello #就是$1参数的输出
world #就是$2参数的输出