shell命令之---操作文件

目录

1、cat:显示或拼接文件内容

2、find:查找并列出文件

3、xargs:给命令传递参数的过滤器

4、tr:转换

5、sort:排序

6、split:文件分割

7、chmod:给文件赋权限

8、touch :生成空白文件或者改变文件的时间信息

9、diff:文件对比工具

10、head、tail:打印文件部分内容

11、ls:列出目录

12、grep:搜索

13、cut:文件切分

14、sed:替换文本

15、awk:处理数据流

 


1、cat:显示或拼接文件内容

     cat本身的意思是concatenate(拼接),用来查看文件的内容、连接文件、创建一个或多个文件和重定向输出到终端或文件。

$ cat file1 file2 file3 ...  #3个文件内容拼接在一起作为输出显示出来
$ cat hello.txt #打印单个文件
$ cat -s file #去掉多余空白行
$ cat file | tr -s "\n"    #去掉多余空白行
$ cat -T file #将制表符标记为^I
$ cat -n file  #在查看文件内容时加上行号
$ cat -b file  #生成行号时跳过空白行
$ cat -e file  #在每一行的末尾显示“$”字符,在需要将多行内容转换成一行时非常有用

2、find:查找并列出文件

      .指定当前目录,..指定父目录,用!可排除掉匹配到的模式

-name 按照文件名查找文件
-iname 匹配时会忽略大小写
-perm 按照文件权限来查找文件 
-user 按照文件属主来查找文件
-group 按照文件所属的组来查找文件
-type 查找某一类型的文件,类型可取值如下:b 特殊块文件(缓冲的),c 特殊字符文件(不缓冲),d 目录,p 命名管道 (FIFO),f 普通文件
-print 使用换行符分隔输出每个文件或目录名
-print0 使用空字符('\0')分隔输出每个文件或目录名,常与xargs命令一起使用
-path 限制所匹配文件的路径及名称
-maxDepth,-minDepth 限制find命令遍历目录的深度
-size n : 文件大小 是 n 单位,b 代表 512 位元组的区块,c 表示字元数,k 表示 kilo bytes,w 是二个位元组
-exec 执行命令,-exec参数后面跟的是command命令,{} 代表前面find查找出来的文件名

-atime 根据用户最后一次访问文件的时间搜索
-mtime 根据文件最后一次修改的时间搜索
-ctime 根据文件元数据(权限)最后一次修改的时间搜索,-表示小于,+表示大于,默认以天为单位,分钟可使用amin,bmin,cmin

经典案例:

$ find . -type f |xargs ls -l  #查找出文件并查看其详细信息
$ find /var/log -type f -mtime +7 -ok rm {}\; #查找/var/log目录中更改时间在7日以前的普通文件,并在删除之前询问它们
$ find / -type f -size 0 -exec ls -l {} \; #查找系统中所有文件长度为0的普通文件,并列出它们的完整路径
$ find / -user fred -or -user george   #在/目录下查找用户是fred或者george的文件文件
$ find /tmp ! -user panda  #在/tmp目录中查找所有不属于panda用户的文件
$ find . -name "*.conf"  -mtime +5 -ok rm {} \; #在当前目录中查找所有文件名以. LOG结尾、更改时间在5日以上的文件,并删除它们,只不过在删除之前先给出提示。
$ find . -type d  |sort #查找当前文件系统中的所有目录并排序

3、xargs:给命令传递参数的过滤器

   它能够捕捉一个命令的输出,然后传递给另外一个命令,由于很多命令不支持|管道来传递参数,而日常工作中有这个必要,所以就有了xargs命令,xargs默认的命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代

$ cat test.txt | xargs		#多行转换成单行
$ cat test.txt | xargs -n3	#-n4指定每行3个字符
$ echo "nameXnameXnameXname" | xargs -dX	#-d 为输入数据指定分隔符
$ find ~ -name '*.log' -print0 | xargs -0 rm -f #删除文件,针对于包含空格的文件
$ find /etc -name "*.conf" | xargs ls –l #获得/etc/ 下所有*.conf 结尾的文件列表
$ find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz #查找所有的jpg 文件,并且压缩它
$ cat args.txt | xargs -I {} sh cecho.sh -p {} -1 #-I {}指定了替换字符串,字符串{}会被从stdin读取到的参数所替换,使用-I时,能循环按要求替换相应的参数

$ cat file | ( while read arg; do cat $arg; done )
$ cat file | xargs -I {} cat {}  #结合stdin,利用while语句和子shell

$ find . -name '*.c' | xargs -I ^ sh -c "echo -ne '\n ^: '; grep main ^" #找出所有的C文件并显示出每个文件的名字,文件名前加一个换行符(-e允许转义替换),文件名后是所有的main行

4、tr:转换

        translate的简写,主要用于压缩重复字符,删除文件中的控制字符以及进行字符转换操作。tr [OPTION]... SET1 [SET2]

-c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
-t 将SET1用SET2转换,一般缺省为-t

eg:
$ echo "aaabbbaacccfddd" | tr -s [abcdf]    #abacfd
$ echo "a1213fdasf" | tr -d [adfs]    #1213
$ echo "a1213fdasf" | tr -t [afd] [AFO]   # A1213FOAsF
$ echo hello    world | tr -s ' '    #hello world

$ tr -d '\n\t' #移除\n\t
$ tr -s ' ' #移除多余的空格  也可以使用 $ sed 's/[ ]\+/ /g'

5、sort:排序

     将文件进行排序并输出,既可以从特定的文件,也可以从stdin中获取输入。常与uniq连用,提取不重复的行。sort(选项)(参数)

-b:忽略每行前面开始出的空格字符;
-c:检查文件是否已经按照顺序排序;
-d:按字典序排列; 
-f:排序时,将小写字母视为大写字母;
-i:排序时,除了040至176之间的ASCII字符外,忽略其他的字符; 
-m:合并排好序的文件;
-k:指定排序所依赖的字符,如果是单个数字,指列号;
-M:按月份的进行排序;
-n:按数字顺序排序;
-r:以相反的顺序来排序;
-t<分隔字符>:指定排序时所用的栏位分隔字符;
+<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。 
  
eg:
$ sort -nk 2 -t: sort.txt     #以“:”为分割符,按第二列的大小进行排序
$ cat 1.txt | sort -r  #反向排序
$ sort test.txt |uniq  #打印输入的行,重复的行只打印一次
$ sort test.txt |uniq -u #打印文件中没有重复出现的行
$ sort test.txt |uniq -d #找出文件中重复出现的行
$ sort test.txt |uniq -c  #统计各行在文件中出现的次数
$ sort test.txt |uniq -s 2 -w 2 #比较跳过前两个字符后的两个字符,重复的行只打印一次

6、split:文件分割

       基本用法:split [-bl] file [prefix]  

-b, --bytes=SIZE:对file进行切分,每个小文件大小为SIZE。可以指定单位b,k,m。
-l, --lines=NUMBER:对file进行切分,每个文件有NUMBER行。
prefix:分割后产生的文件名前缀
-d:使用数字后缀,不加默认使用字母后缀
-a length:指定后缀长度
-l no_of_lines:根据行数来分割文件,默认按照块大小分配

$ split -b 10k data.file -d -a split_file #10K为一个文件,分割后的文件名以四位数字为后缀

      额外的,mktemp命令专门用来创建临时文件,并且其创建的临时文件是唯一的

-q:执行时若发生错误,不会显示任何信息;
-u:暂存文件会在mktemp结束前先行删除;
-d:创建一个目录而非文件。

   其次:借助%操作符可以轻松将名称部分从“名称.扩展名”中提取出来文件名。借助#操作符可以将文件名的扩展名部分提取出来

file_jpg="sample.jpg"
name=${file_jpg%.*}
echo File name is:$name  #File name is:sample

extension=${file_jpg#*.}
echo Extension is:jpg    #Extension is:jpg

说明:

${file_jpg%.*}的含义是:从$file_jpg中删除位于%右侧的通配符所匹配的字符串,通配符从右向左进行匹配。

${file_jpg#*.}的含义是:从$file_jpg中删除位于#右侧的通配符所匹配的字符串,通配符从左向右进行匹配。

%属于非贪婪操作,它从右到左找出匹配通配符的最短结果。

%%属于非贪婪操作,它从右到左找出匹配通配符的最长结果。

#属于非贪婪操作,它从左到右找出匹配通配符的最短结果。

##属于非贪婪操作,它从左到右找出匹配通配符的最长结果。

var=dir/filename.suf

${var##*/} 删除左起最后一个‘/'字符及其左边的内容:filename.suf
${var#*.}   删除左起第一个‘.’字符及其左边的内容    :suf
${var%%/*} 删除右起最后一个‘/’字符及其右边的内容:dir
${var%/*}  删除右起第一个‘/’字符及其右边的内容:dir
${var:0:5} 左边第1个字符开始,及5个字符
${var:7}    左边8个字符开始至结束
${var:0-7:3}右边第7个字符开始,及3个字符
${var:0-7} 右边第7个字符开始至结束

7、chmod:给文件赋权限

       chmod[u,g,o][+,-,=][r,w,x] 文件

   u:user,表示文件的创建者,即文件的属主;
   g:group,表示和属主在同一个组的;
   o:others,表示和u与g八辈子都打不着杆儿的其他用户;
   +表示给相应的用户增加权限;
   -表示给相应的用户去除权限;
   =表示给相应的用户赋予权限,具有覆盖作用哦;
   r表示读权限,即有此权限的用户可以读文件的内容;
   w表示写权限吗,即有此权限的用户可以往文件里写东西;
   x表示执行权限,即有此权限的用户可以执行文件;

8、touch :生成空白文件或者改变文件的时间信息

touch file1:创建一个空白文件。
-a:access,只改变访问时间。
-c:不创建任何文件。
-m:modify,只改变修改时间。
-r:replace,用指定文件的时间代替当前时间。
-d:将时间戳更改为当前时间,也可以指定特定的时间和日期

9、diff:文件对比工具

diff [options]  file1.txt  file2.txt # file1为比较文件 file2为基准比较文件.

-b:不检查空格
-B:不检查空白行
-i:不检查大小写
-w:忽略所有的空格
--normal:正常格式显示(默认)
-C:上下文格式显示

-u:合并格式显示
-N:将缺失的文件视为空文件
-a:将所有的文件视为文本文件
-r:递归遍历目录下的所有文件

10、head、tail:打印文件部分内容

        head命令用于打印指定输入的开头部分内容,默认情况下,打印每个指定输入的前10行内容,-n选项可以指定打印文件的前N行,-c选项打印文件的前N个字节的数据。tail命令,它打印指定输入的结尾部分的内容。默认情况下,打印指定输入的最后10行的内容,-n选项可以指定打印文件的最后N行,f选项可以同时使用,可以在特定的进程结束时终结tail命令

$ seq 100 | tail -n +6 #打印除了前5行之外的所有行
$ tail -n 5 file #打印最后五行

11、ls:列出目录

#列出当前路径下的目录
$ ls -d */
$ ls -F |grep "/$"
$ ls -F |grep "^d"
$ find . -type d -maxdepth 1 -print
ls -d 显示当前目录的上层目录,不显示子目录
ls -a 显示当前目录下的所有子目录,包括隐藏的文件
ls -l 显示当前目录下所有文件的所有信息(除隐藏文件夹外)文件名 子目录的权限 使用者 文件大小 等
ls -s 在每个文件后面显示文件的大小(我觉得-s 表示的是size的意思)
ls -k 树上说以k字节的形式表示文件的大小(我未曾直观的看到怎样以k 字节表示)
ls -u 以文件上次访问的时间排序(我试出来的结果是倒序)
ls -t 以时间排序(应该是以最近访问排序)
ls -o显示除组信息外的气其他详细信息
ls -x 按列输出横向排序
ls -r 对目录反向排序
ls -q 用“?”表示不可输出的字符(简单尝试为看出效果)
ls -m 横向输入文件名,并且用“,”作为分隔符
ls -S 以文件大小排序(注意大写)
ls -R列出所有子目录下的文件
ls -pF在文件后面附上一个字符说明文件的类型。“×”表示可执行文件,“/”表示目录,“@”表示符号链接,“|”表示FIFo(FIFO表示管道,),“=”表示套接字
ls -C 按列输出,纵向排序
ls -Q 把输出的文件名用双引号括起来

12、grep:搜索

          grep   匹配条件   处理文件

-E:使用扩展的正则表达式,或者可以使用egrep
-o:只显示被模式匹配到的字符串,而不是整个行
-v:反向选取,只显示不符合模式的行
-c:统计出匹配模式的文本行数(一行出现多次算一次)
-n:打印出匹配字符串所在行的行号
-b:打印出匹配出现在行中的偏移量
-l:列出匹配模式所在的文件,-L返回不匹配文件的列表
-i:匹配时不区分大小写
-r:递归的搜索
-e:指定多个匹配模式
--color:在输出行中着重标记出匹配到的模式
-A:打印出匹配结果之后的行
-B:打印出匹配结果之前的行
-C:打印出之前和之后的N行
-q:静默输出,0表示成功,非0表示匹配失败


$ echo -e "1 2 3 4\nhello\n5 6" | egrep -0 "[0-9]" | wc -l #统计文件中匹配项的数量
$ grep "main()" . -r --include *.{c,cpp} # 在目录中递归搜索所有.c,.cpp文件

13、cut:文件切分

      提取指定位置或列之间的字符 cut(选项)(参数)

-b:仅显示行中指定直接范围的内容;
-n:与“-b”选项连用,不分割多字节字符;
-c:仅显示行中指定范围的字符;
-d:指定字段的分隔符,默认的字段分隔符为“TAB”;
-s: 禁止打印没有分隔符的行
-f:显示指定列的内容,多个用逗号隔开
--complement:补足被选择的字节、字符或字段; 
--out-delimiter=<字段分隔符>:指定输出内容是字段分割符; 

cut命令可以指定字段的字符或者字节范围
N- :从第N个字节、字符、字段到结尾
N-M :从第N个字节、字符、字段到第M个(包括M在内)字节、字符、字段;
-M :从第1个字节、字符、字段到第M个(包括M在内)字节、字符、字段。
-b 表示字节;
-c 表示字符;
-f 表示定义字段

$ cut -f2 --complement test.txt #打印除了第二列之外的列
$ cut -c1-3 test.txt #打印第1个到第3个字符
$ cut -c-2 test.txt # 打印前2个字符
$ cut -c5- test.txt # 打印从第5个字符开始到结尾

14、sed:替换文本

       sed是一种支持正则表达式的交互式流编辑器(stream editor), 脚本中文本替换的最佳工具。sed [选项] '[动作]' 文件

a :新增,当前行的下一行
d :删除,删除选择的行。
i :插入,当前行的上一行.
p :打印,通常 p 会与参数 sed -n 一起运行.
s :替换,替换指定字符,通常与正则表达式联用。
g: 标记为全局替换,/#g 标记可以替换第N次出现的匹配

sed中使用正则表达式:
& 已匹配字符标记
\1,\2  子串匹配标记
^$ 匹配空行
多个命令之间用分号相隔,或使用 -e


$ sed -i "3i\test123" aa.txt # 在第三行的上方添加一行字符串
$ sed -i "3a\ceshi456" aa.txt # 在第三行的下方添加一行字符串
$ sed -n '1,$p' /etc/hosts # 输出文件所有内容
$ sed ':t;N;s/\n/,/;b t' /etc/hosts # 将每行内容放到一行上进行展示,每行内容以逗号进行分隔。
$ sed -n "2,4p" /etc/hosts # 输出第二行到第四行之间三行的内容
 【$p为最后一行的意思,'1,$p',是选择打印第一行到最后一行。必须用单引号表示,双引号会报错。】
$ sed -i "5s/port:.*/port: $2,/g" ../Gruntfile.js  #指定行号匹配替换
$ sed 's|te\|xt|replace|g' #s命令之后的字符视为分隔符,\|是出现在模式中转义后的分隔符
$ sed '/^$/d' file  # 删除匹配到的空行
$ sed 's/$//'  #  $是最后。在每一行后面追加空。
$ sed -e '1,5d' -e 's/hello/hi/' sed.txt 
$ sed --expression='s/hello/hi/' --expression='/today/d' sed.txt    # 删除1至5行,并用hello替换hi

$ sed 's/[ ]\+/ /g'   #移除多余的空格  也可以使用 $ tr -s ' ' 
$ sed 's:/\*.*\*/::g' #移除注释
$ sed 's/ \?\([{}();,.]) \?/\1/g' #移除{,}(,);:之间的空格

$ find . -name *.cpp -print0 | \ xargs -I{} -0 sed -i 's/Copyright/Copyleft/g' #将所有.cpp文件中的Copyright替换为Copyleft。-print0打印出以\0位分隔符的文件列表。
或者使用命令:$ find . -name *.cpp -exec sed -i 's/Copyright/Copyleft/g' \{\} \;
或者 $ find . -name *.cpp -exec sed -i 's/Copyright/Copyleft/g' \{\} \+

15、awk:处理数据流

      awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file

      [-F|-f|-v]   大参数,-F指定分隔符(默认分隔符是空格),-f调用脚本,-v定义变量 var=value

特殊变量:
$0           表示整个当前行
$1           每行第一个字段
NF          字段数量变量
NR          每行的记录号,多文件记录递增
FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始
FS          BEGIN时定义分隔符
RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~            匹配,与==相比不是精确比较
!~           不匹配,不精确比较
+            匹配时表示1个或1个以上
OFS      输出字段分隔符, 默认也是空格,可以改为制表符等
ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕

此外,还包括一些内置函数:https://blog.csdn.net/weixin_33968104/article/details/89658135?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159646886219724835830446%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159646886219724835830446&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v2-1-89658135.first_rank_ecpm_v3_pc_rank_v2&utm_term=shell+awk%E5%91%BD%E4%BB%A4+%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0&spm=1018.2118.3001.4187 

$ awk '{print}' text.txt  #输出文件全部内容
$ awk -F: '{print $1; print $2}' /etc/passwd  #将每一行的前二个字段,分行输出
$ ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' #计算文件大小
$ awk '{print NR,$0}' /etc/passwd       #输出每行的行号
$ awk '!/mysql/{print $0}' /etc/passwd     #输出不匹配mysql的行
$ awk '/101/' file     #显示文件file中包含101的匹配行 
$ seq 5 | awk 'BEGIN { getline; print "\nRead ahead first Line",$0} {print $0}'  #通过getline命令读取行。
$ echo | awk -v VAR=$var '{print VAR}' # 利用-v传递外部变量值给awk
$ awk '{ for(i=1;i<NF;i++) {print NF,$i}}'   #file 通过for语句实现循环。
$ awk 'NR==M, NR==N' fileName #打印从M行到N行之间的文本,或者使用$ cat fileName | awk 'NR==M, NR==N'
    

 

其他:

1)rename:文件重命名

$ rename *.JPG *.jpg  #将 *.JPG更名为 *.jpg
$ rename 's/ /_/g' * #将文件名中的空格替换成字符 “_”
$ find path -type f -exec rename 's/ /_/g' {} \; #以递归的方式将所有文件名中的空格替换为字符"_"

2)dd:创建特定大小文件。会克隆给定的输入内容,然后一模一样的一份副本写入到输出。

      详见:http://blog.chinaunix.net/uid-24958038-id-3416169.html

$ dd if=/dev/hda of=/root/image count=1 bs=512 #备份磁盘开始的512个字节大小的MBR信息到指定文件

3)comm:用于比较已经排序的文件,对输入的两个文件进行比较,输出3列数据,分别是1>仅在file1中出现的行2>仅在file2中出现的行3>在两个文件中都存在的行。

$ comm 1.txt 2.txt -2 -3  #1.txt的差集
$ comm 1.txt 2.txt -1 -3  #2.txt的差集

4)chattr:更改文件扩展属性

$ chattr +i  /etc/shadow    #将文件设为不可修改
$ chattr -i  /etc/shadow     #解除不可修改设置

5) tac:逆序打印,默认使用\n作为分隔符,使用-e来指定分隔符

$ seq 5 | tac   #以逆序形式打印行

   


 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页