1 列出文件目录
ls 文件名列表
- 在同一命令行中可以指定0~n个实参
- 不给出实参时,列出当前目录下所有文件和目录;
- 实参为文件时,列出文件项;
- 实参为目录时,列出目录下的所有文件。
(1)选项 -F (Flag)
- 列出的是目录,名字后面缀以斜线 /,bin/
- 列出的是可执行文件,名字后面缀以星号 *,zap*
- 列出的是符号连接文件,名字后面缀以 @,Unix@
- 列出的是普通文件,名字后面无任何标记
(2)选项 -l 长格式列表
例:ls -l arg
- -rwxr-x--x l liang stud 519 Jul 5 12:09 arg
第1列:文件属性
- - 普通文件
- b 块设备文件(Block)
- d 目录文件(Dir)
- c 字符设备文件(Char)
- l 符号连接文件(Link)
- p 命令管道文件(Pipe)
文件的访问权限(rwx 分别为读,写和可执行权限)
- 2-4字符:文件所有者对文件的访问权限
- 5-7字符:同组用户对文件的访问权限
- 8-10字符:其它用户对文件的访问权限
第2列:文件的Link数,涉及此文件的目录项数
第3列:文件主的名字
第4列:文件组的组名
第5列:
- 普通磁盘文件:列出文件大小(字节数)
- 目录:列出目录表大小,不是目录下文件长度和
- 符号连接文件:列出符号连接文件自身的长度
- 字符设备和块设备文件:列出主设备号和次设备号
- 管道文件:列出管道内的数据长度
第6列:文件最后一次修改的日期和时间
第7列:文件名
(3)其他选项
- -h (human-readable),许多其他命令中也有类似选项。以便于人阅读的方式打印数值(例如:1K 23M 4G)
- -d 当ls的参数是目录时,不像默认的情况一样列出目录下的文件,而是列出目录自身的信息
- -a (all) 列出文件名首字符为圆点的文件(默认情况下这些文件不列出,经常用于保存用户的偏好设置信息或保存某些软件的状态信息)
- -A (功能与-a相同,除了出列出 . 和 ..)
- -s (size) 列出文件占用的磁盘空间
- -i (i-node) 列出文件的i节点号
2 文件的复制与删除
2.1 cp 拷贝文件
(1)cp file1 file2
- file2不存在,则创建;
- file2存在且是文件,则覆盖;
- file2存在且是目录,则拷贝到目录下面。
(2)cp file1 file2 ... filen dir
- dir 必须是已有目录名。
举例:
- cp downc/p*.c . # 将downc目录下的所有可以和p*.c进行通配的文件拷贝到当前目录下。
2.2 mv 移动文件
(1)mv file1 file2
- file2不存在时,相当于给file1重命名为file2。
- file2存在时,会进行覆盖重命名。(即将原始的file2覆盖掉,然后将原始的file1文件重命名为file2)
(2)mv file1 file2 ... filen dir
- dir 必须为当前已经存在的目录。
- 将dir前面所列的文件移动到dir的目录下面。
(3)mv dir1 dir2
- dir2不存在时,将dir1改名为dir2;
- dir2存在时,将dir1整体移动到dir2下面作为dir2的子文件。
2.3 rm 删除文件
(1)rm file1 file2 ... filen
- 删除rm后面所列出的所有文件。
- 当后面有文件通配符时需要注意,shell会根据文件通配符进行转换,然后进行删除。
(2)选项
- -r 递归地(Recursive)删除实参表中的目录,也就是删除一整颗目录树。
- -i 每删除一个文件前需要操作员确认(inform)。
- -f 强迫删除(Force),只读文件也可删除,但是非操作用户权限之内的文件是无法删除的。
2.4 显示区分命令选项和处理对象
问题:如果使用 ls>-i 生成了文件 -i,但是利用 rm -i 将无法删除该文件,系统会认为 -i 是选项。
解决方法
- 大多数linux命令(如cp, ls, mv, rm, cat, grep, set等)用 -- 显式地标志命令行选项的结束,识别以 - 开头的处理对象。
- rm -- -i # 删除文件 -i,前面的 -- 告诉系统选项的结束。
- grep -1 ht.c # 本意是在文件中查找 -1,但是系统会将 -1默认为选项。
- grep --help *.c # 本意是找 --help,但是该操作会使得系统将 --help 默认为命令行参数。正确应该是 grep -- --help *.c。
3 目录管理
3.1 路径名
文件 . 与 ..
- 在目录表中确实有这两个文件;
- 这两个目录项由系统创建和删除。
主目录(Home Directory)
- 每个用户都有自己独立的主目录;
- 用 env 命令查环境变量 HOME 的值。
绝对路径名与相对路径名
- 路径分量分割符用斜线 / ,而不是反斜线 \(这里linux 和 windows系统是不同的)
- 例如 /home/stud/liang # 以 / 开始为绝对路劲
- test/case/conf # 以当前工作目录为起始的相对路径
3.2 当前工作目录相关命令
当前工作目录是进程属性的一部分,每个进程都有一个。
(1)pwd 命令
(print working directory)打印当前工作目录
(2)cd 命令
(change directory)改变当前工作目录。同时 cd 是shell的一个内部命令,外部命令在shell执行过程中需要到磁盘中寻找响应的处理文件,但是对于内部命令shell可以直接处理,不需要去磁盘寻找。
- cd /user/include # 切换目录
- cd .. # 返回上一级目录
- cd # linux 中回到用户的主目录
(3)mkdir / rmdir 命令
mkdir 命令 创建目录
- 选项 -p,自动创建路劲中不存在的目录。
- mkdir -p database/2021/12/09/log # 即使没有某些目录,但是该命令仍旧会在指定目录下创建log文件;如果没有-p,当没有某些目录时就会报错。
rmdir 命令 删除目录
- 该命令使用较少,因为要求被删除的目录除了 . 与 .. 外无其他文件或目录。
- 通常使用 rm -r sun/work.c 通过递归的删除所有目录下的文件。
(4)cp 命令 复制目录
选项 -r 递归地复制一个目录。cp -r dir1 dir2
- dir2不存在,则新建子目录dir2,把dir1下的内容拷贝到dir2下;
- dir2存在,则dir2下新建子目录dir1,把dir1的内容拷贝到dir2/dir1下面。
选项 -v 冗长(verbose)方式
- 复制目录时实时列出正在复制的文件的名字。
选项 -u 增量拷贝(update),便于备份目录
- 根据文件的时间戳,不拷贝相同的或者过时的版本的文件,以提高速度。
- dir1和dir2不慎颠倒位置,不会出现灾难性后果。
命令 touch
- 将文件的最后一次修改时间设置为当前时间,但不修改文件的内容。
- 例如:touch *.[ch],该命令可以和 -u 配合使用。
(5)rsync 数据备份工具(增量拷贝工具)
功能:
远程同步remote sync,可以镜像整个目录树。
问题:
网络中两个主机A和B,都有一个二进制的大型数据文件big.dat,文件在A上做了改变成为了新版本的big.dat,需要让B也得到新文件。(此时进行拷贝操作也很浪费时间)
解决方法:
rsync用一精巧的算法,将文件分块,在两主机间传播数据块的hash值,据此推断出两个版本之间区别,使得网络只传输文件的增、删、改部分。(优化流程,利用增量文件传输,具有更高的效率)
4 目录遍历命令
4.1 find 遍历目录树
基本功能
- find命令从指定的查找范围开始,递归地查找子目录(需要给出查找范围)
- 凡满足条件的文件或目录(find遍历需要依据的条件)
- 执行规定的动作(遍历到满足的条件,需要执行相关的动作)
举例
- find ver1.d ver2.d -name '*.c' -print
- 范围:当前目录的子目录ver1.d 和 ver2.d
- 条件:与名字*.c匹配。注意必须用 ‘’ 括起来
- 动作:把查找到的文件的路径名打印出来
命令特点
- 功能强大,选项多;递归式查找,提供了一种遍历目录树的手段。
- 在“动作”中可以指定任何命令(包括用户自己编写的处理程序),使得find成为一个任意处理命令,可以借用来进行目录遍历的壳(类似awk对文本的逐行扫描,find对目录森林中的文件和目录逐个扫描)。
4.2 find条件选项
-name <‘wildcard’>
- 文件名与wildcard匹配。
- 必须有引号,对通配符的解释由find完成,这里的文件名仅仅指路径名的最后一部分。
-regex <pattern>
- 整个路径名与正则表达式pattern匹配。
-type <char>
- f 普通文件 d 目录 l 符号连接文件
- c 字符设备文件 b 块设备文件 p 管道文件
-size +/-n 单位
- 指定文件大小(大于+,等于,小于-)
- 单位有c(字符),b(块,512字节),k(1024),M(兆),G(吉),默认为b
-mtime +/-ndays 文件最近修改时间
-newer file 文件最近修改时间比file的还晚
4.3 find动作选项
- 打印查找的文件的路径名
-exec
- 对查找到的目标执行某一命令;
- 在-exec及随后的分号之间的内容作为一条命令。在这个命令的命令参数中,{}代表遍历到的目标文件的路径名。
-ok
- 与-exec类似,只是对查找到符合条件的目标执行一个命令前需要经过操作员确认。
5 目录遍历应用
5.1 find使用举例
(1)find . -type d -print
- 从当前目录开始查找,寻找所有目录,打印路劲名
- 结果:按层次列出当前的目录结构。
(2)find / -name 'stud*' -type d -print
- 从根目录检索找出名字为stud*的目录
- 指定两个条件:名字与stud*匹配,类型为目录。两个条件为“与”,即必须同时满足才可。
(3)find / -type f -mtime -10 -print
- 从根目录开始检索最近10天之内曾经修改过的普通磁盘文件(目录不算)
(4)find . ! -type d -links +2 -print
- 从当前目录开始检索link数大于2的非目录文件。!表示“非”。
- 注意:! 与 -type 之间必须保留一空格。
(5)find ~ -size +100k \( -name core -o -name '*.tmp' \) -print
从主目录开始寻找大于100KB的名叫core或有.tmp后缀。
- 使用了两条件“或” (-o)及组合(圆括号)。-o 的含义为或
- 注意不要遗漏所需要的引号,反斜线和空格,尤其是圆括号前和圆括号后。圆括号是shell的特殊字符。
- 其他写法1: find / -size +100k \( -name core -o -name '*.tmp' \) -print
- 其他写法2: find / -size +100k '(' -name core -o -name '*.tmp' ')' -print
(6)find /lib /usr -name 'libc*.so' -exec ls -lh {} \;
- 在/lib 和 /usr范围中查找。-exec命令到 ; 截止。
- shell中的分号有特殊含义,所以前面一定要加反斜线\;
- {}代表遍历时所查到的符合条件的路径名。{}中间没有空格,之后的空格不可以省略。{}表示命中查找的目标。
5.2 find递归搜索字符串
利用find的递归式遍历目录的功能在文件中搜寻字符串
- find src/tools ! -newer test.dat \( -name '*.c' -o -name '*.h' \) -exec grep -n -- --help {} /dev/null \;
在目录src/tools中查找修改时间比test.dat更晚的文件,且同时要找到的文件名为*.c或者*.h文件;在满足上述条件的结果中应用-exec命令,即通过grep命令查找--help,-n为显示行号,{}为匹配所有前面命中的结果(因为grep命令在只有一个文件时,不显示找到的信息具体在那个文件中,所有增加了/dev/null,使得结果里面可以显示行号和文件名。/dev/null文件类似黑洞文件,读的时候为空,写的时候为黑洞)。
该命令在使用中需要特别注意转义字符、括号等信息。
-print -exec ls -l {} \; 上述命令之后增加该命令可以打印文件信息。
6 批量处理文件
6.1 find与-exec组合遍历
在5.2节中利用find的“壳”功能去遍历目录,对遍历到的每个符合条件的文件执行grep命令。
缺点:效率低下,因为每个命中的对象都需要执行grep命令,创建一个进程,完成任务后进程消亡,然后再创建,再消亡,......。这样下去会启动非常多的进程来执行find遍历操作。
grep 命令提供了 -r 选项(递归查找),可以递归搜索子目录下的文件
- 例如:grep -nr -- --help *.c 这样无法检索,因为那些子目录下的文件名字无法被 *.c 匹配。
- grep -nr -- --help * 这样可以检索,但是却检索了太多非C源程序的不需要的文件,输出结果会被淹没在无用的信息中,应当使用find精确筛选的功能。
6.2 利用find与xargs的组合
- find src -name \*.c -exec grep -n -- --help {} /dev/null \;
上述命令存在问题(需要创建多个进程),如果能够把
- find src -name \*.c --print
生成的文件名列表追加在下列命令后面就可以了。这样只需要创建一个进程,大幅提高了效率。
- grep -n -- --help <filelist>
命令xargs可以用来完成这个工作:
- find src -name \*.c --print | xargs grep -n -- --help
xargs 命令把标准输入追加到它的参数列表后面,也就是上述 grep... 的后面,再作为一个命令来执行。这样利用 find 精确筛选,利用 grep 批量处理文件,提高效率。
- 命令1: find src/tools ! -newer test.dat \( -name '*.c' -o -name '*.h' \) -exec grep -n -- --help {} /dev/null \;
- 命令2: find src/tools ! -newer test.dat \( -name '*.c' -o -name '*.h' \) --print | xargs grep -n -- --help
命令2的效率要远远高于命令1,可以通过 time (<command>) 测试执行时间。
(1)xargs 将标准输入组织程命令执行
- 将标准输入构造为命令的命令行参数。
- 如果标准输入的数据量很大,xargs指定的处理程序会启动多个进程运行,每个进程处理一批,会是几千个参数(命令行参数沾满128K字节)。
- 可以使用xargs的-n选择指定每批次处理多少个。
- xargs经常与find配合使用,也可以与其他命令组合使用。本来xargs从标准输入获取,可以转为从管道获取。
(2)xargs 构造参数列表并运行命令
解决shell文件名生成时,因为文件太多,缓冲区空间受限而文件名展开失败的问题(文件名展开,即在shell里面将通配符等展开程全称的形式)。
- rm -f *.dat # 当*.dat文件太多时,可能会展开失败,可以使用下面命令替换
- ls | grep ".dat$" | xargs rm -f
find 命令中目录名因删除目录导致目录遍历过程遇到麻烦
- find . -name CVS -exec rm -rf {} \;
- 改为:find . -name CVS -print | xargs rm -rf
7 打包与压缩
7.1 tar 文件归档
功能:最早为顺序访问的磁带机设备而设计的(Tape ARchive,磁带归档),用于保留和恢复磁带上的文件。
语法
tar ctxv[f device] file-list
选项第一个字母指定要执行的操作,是必需的
- c:Creat创建新磁带。从头开始写,以前存于磁带上的数据会被覆盖掉。
- t:Table列表。磁带上的文件名列表,当不指定文件名时, 将列出所有的文件。
- x:eXtract抽取。从磁带中抽取指定的文件。当不指定文件名时,抽取多有文件。
除功能字母外的其他选项
- v:Verbose冗长。每处理一个文件,就打印出文件的文件名,并在该名前冠以功能字母。
- f:Flie。指定设备文件名。
- z:采用压缩格式(gzip算法)
- j:采用压缩算法(bzip2算法)
举例
- tar cvf /dev/rct0 . # 将当前目录树备份到设备 /dev/rct0 中,圆点是当前目录。
- tar tvf /dev/rct0 # 查看磁带设备 /dev/rct0 上的文件目录。
- tar xvf /dev/rct0 # 将磁带设备 /dev/rxt0 上的文件恢复到文件系统中。(简单理解就是通过cvf可以打包文件,然后将打包文件拷贝到需要的地方,然后通过xvf可以将打包好的文件解压恢复出来)。当需要压缩文件大小时,可以增加 z 或者 j。
- tar cvf my.tar *.[ch] makefile # 将*.[ch] 和 makefile 文件打包放到my.tar里面。
7.2 压缩与解压缩
gzip / gunzip 执行速度快
bzip2 / bunzip2 占用较多的CPU时间
- gzip file # 利用算法gzip压缩文件file
- gunzup file # 利用算法gzip解压缩
- bzip2 file # 利用算法bzip2压缩文件
- bunzip2 file # 利用算法bzip2解压缩
注意使用tar压缩命令时要规范格式,不然容易造成文件损坏。