linux shell脚本攻略 学习笔记3 -- 第三章 以文件之名

原创 2015年07月09日 21:24:23

第三章主要跟文件的处理相关,小结各节内容如下:


1,简介

概念:Unix将系统中的一切都视为文件;如普通文件、目录、终端、符号链接、命名管道等等,都是一种文件;

 

2, 生成测试用的文件

1)某些时候,需要制作一些测试用的文件,我们不用单独写程序去生成,可以直接采用现有的dd命令;

由于上一章已有介绍,此处仅举例如下:

$ dd if=/dev/zero of=test.data bs=1M count=2     #生成一个1M*2=2M的内容全为0的文件test.data

 

2)另,可以使用dd命令传输大量数据,来测试当前内存的操作速度,如使用1)中命令语句后,会有以下类似打印:

2+0 recordsin

2+0 recordsout

2097152 bytes (2.1 MB) copied, 0.00660423s, 318 MB/s

 

3,文本文件的交集和差集

1)理解交集和差集,以及求差

举个例子:A {1, 2,3}, B {3, 4, 5}

交集,两个文件共有的行,例中为 {3}

求差,两个文件所不同的那些行,例中为 {1, 2, 4, 5}

差集,仅在A文件中的行或仅在B文件中的行,例中为A差集{1, 2},B差集{4, 5}

 

2)使用命令comm, compare two sorted files line by line

格式 comm file1file2

注,file1、file2应该为排序后的文件(有重复行也可以)

例:

$ cat afile

a

b

b

c

d

$ cat bfile

a

d

f

$ comm afile bfile

                a

b

b

c

                d

       f

解释,comm的结果,第一列为afile仅有的行,第二列为bfile仅有的行,第三列为afile bfile都有的行;各列以\t分割;

 

3)可用选项,得到交集、求差、差集

-1,comm结果中删除第1列;

-2,comm结果中删除第2列;

-3,comm结果中删除第3列;

则,获取交集的语句:commafile bfile -1 -2

获取求差的语句:commafile bfile -3 | sed ‘s/\t//’

获取A的差集:comm afile bfile -2 -3(B的差集相似)

 

注,上面例子有有sed的使用,有个知识点记录下:

区别下面两语句,

sed 's///'          只替换第一个匹配字符

sed 's///g'         替换所有匹配字符

例:

$ echo "aaaabbbbbcccccccaaaaa" |sed 's/a/A/g'

AAAAbbbbbcccccccAAAAA

$ echo "aaaabbbbbcccccccaaaaa" |sed 's/a/A/'

Aaaabbbbbcccccccaaaaa

 

4,查找并删除重复文件

这个小节写了一个脚本,利用了md5sum、comm、awk、xargs、rm、ls等各shell工具,来完成删除重复文件的任务;

代码似乎有问题,使用不通过,还没弄清楚,暂不做记录...

 

5,创建路径目录 mkdir

基本使用:mkdir dirpath

使用参数:mkdir –p dirpath,使用-p,可以忽略所有已存在目录,并创建缺少的部分;

例子:

$ mkdir testdir

mkdir: cannot create directory `testdir':File exists

$ mkdir testdir/adir

$ tree testdir/

testdir/

`-- adir

$ mkdir -p testdir/adir/bdir/cdir

$ tree testdir/

testdir/

`-- adir

   `-- bdir

       `-- cdir

 

6,文件的权限、所有权、setuid、setgid、粘滞位

ls –l,看出文件属性,如下:

-rw-r--r-- 2 philip philip 29 Jul  5 22:56 hardafile

lrwxrwxrwx 1 philip philip 10 Jul  5 22:57 symbolafile -> afile

1)权限、所有权

权限为rwxrwxrwx这9位内容,三位分割分别对应用户、组、其它的读、写、执行权限;

所有权为philip philip,分别对应拥有用户和拥有组;

 

2)setuid、setgid

setuid,设置用户ID位;setgid,设置用户组ID位:个人理解,当前用户对该文件具有 文件拥有者所具有的权限;setuid出现在用户的可执行位上,如rwS------,setgid出现在组的可执行位上,如---rwS---

 

3)粘滞位

目录才有该属性,放在可执行位上,表示对该目录具有写权限的用户在满足以下条件时才能删除目录中的文件:拥有此文件、或拥有此目录、或为root;

可执行且无粘滞位       --x

可执行且粘滞位           --T

不可执行且粘滞位       --t

注,粘滞位以前还有别的意思,可见apue p83

 

4)相关设置命令 chmod chown

看例子:

chmod u=rwxg=rw o=r filename,u 用户,g 组,o 其它

chmod u+x filename

chmod a+r filename,a表示all

chmod o-w filename

chmod 764 filename,用户为7,对应rwx(111);组为6,对应rw-(110);其它为4,对应r--(100);

chmod +s filename,设置setuid、setgid;

chmod a+t filename,设置粘滞位;

chmod 777 –R.     ;-R,递归方式

 

chown root /u

change the owner of /u to "root".

chown root:staff /u

likewise, but also change its group to "staff".

chown -hR root /u

change the owner of /u and subfiles to "root".

chown user.group –R    ;-R,递归方式

 

7,创建不可删除文件

在ext2、ext3、ext4等文件系统中,可创建不可修改(immutable)文件,命令用chattr;

chattr - change file attributes on a Linuxfile system

chattr +i filename,变为不可删除;i,immutable;

chattr –i filename,变回可删除;

 

8,生成(空白)文件

touch命令,生成空白文件,但如果文件存在,则touch用来修改文件的时间戳;

格式:touch filename,创建新文件或更新时间戳到现在;

touch –a filename,只更新access time;

touch –m filename,只更新modif time;

touch –d “Jan 20 2010”filename,更新到-d所指示的时间;

 

9,符号连接,ln

ln命令

-s, --symbolic        make symbolic links instead of hard links,而直接ln target symbol则为硬连接

-L,logical            make hardlinks to symbolic link references,对符号连接所指向的文件进行硬连接

 

a,harda,symbola,harda为a的硬链接文件,symbola为b的符号链接文件;理解硬链接和符号连接:

1)a和harda指向同一内容(inodes),但连接点数量加1;symbola是一个新文件;

2)删除a,harda没事,symbola 将打不开了

 

找符号链接文件的方法:

1) ls –l | grep “^l”

2) find . –type l

 

另:读一个符号链接所指向的源文件,命令readlink(print value of a symbolic link or canonical file name),如

$ readlink web

/var/www

 

10,列举文件类型统计信息

本小节是一个运用示例,统计某目录下文件类型的信息;

1)区别文件类型的几个工具,find –type, ls –l, file,具体示例如下:

find :

$ declare –A count

$ count[“file”]=`find . –type f | wc | awk ‘{print$1}’        #注意,可以用关联数组进行统计

 

ls :

$ ls –l dir | grep “^d” | wc -l

 

file :

file filename

file –b filename      #-b, brief

 

2)写脚本程序时,遇到return和exit的使用:

脚本任意处可以用exit退出脚本程序;

return,can only `return' from a function or sourced script,即return用在function和sourced script,对于sourced script的理解:进行了实验,在脚本中function外加return语句,则如果由./script运行,则会出现上面的错误提示,需改为source script进行运行则正常;具体原理还不清楚;

 

3)for file in $all_files         #all_files是想包含所有文件名,形如”aa bb cc dd”;但如果某文件的名字中有

       …                                    #空格,如上面例子中有一个文件就叫”cc dd”,这样for会将cc、dd拆分,

                                               #以为有两个文件,导致处理出错

 

一种改进的方式:

       while read line                     #filename为一个文件名,文件内的内容在本小节例子中为所有文件的名字,以

       do                                          #换行符分割;如下

              something                     #     aa

       done< filename                   #     bb…

       while read line                     #上面是以文件内容作为stdin,然后给read去读

       do                                          #这里只是用子进程的输入作为stdin,注意子进程前面有一个”<”

              something

       done< <(find .)

 

 

4)注意,脚本中变量名最好加上””,以避免有空格的变量字符串!

 

11,环回文件与挂载

12,生成ISO文件与混合ISO

上面两小节先不做小结,个人觉得使用的机会会小点

 

13,查找文件差异及进行修补 diff与patch命令

13.1 查找差异 diff命令

基本使用:

$ diff afile bfile

2c2

< 345

---

> 346

一体化形式的diff(结果可读性更好):

$ diff -u afile bfile

--- afile   2015-07-0818:17:07.082191414 -0700

+++ bfile 2015-07-0817:46:16.986140468 -0700

@@ -1,3 +1,3 @@

 123

-345

+346

 asd

 

13.2 修补,即打patch,patch命令

首先由diff生成patch文件,可以diff afile bfile > ab.patch或diff –u afile bfile > ab.patch;

然后patch –p1afile < ab.patch,将patch打到afile上,此后afile与源bfile一样;

       patch–p1 bfile < ab.patch,将patch打到bfile上,此后bfile与源afile一样;

会有打印:“patchingfile afile”

注:-pnum参数的含义,Strip the smallest prefix containing num leading slashes from each file  name found  in the  patch  file.将patch中的文件名字,删去前num个斜杠及斜杠前面的内容;具体含义man或网上查资料吧;

 

13.3 恢复,使用与修补同样的命令,即

patch –p1 afile < ab.patch,对bfie同理;

会有打印:

patching file afile

Reversed (or previously applied) patchdetected!  Assume -R? [n]

如果使用patch –R –p1 afile < ab.patch则不会出现-R提示;

 

13.4 针对目录生成diff信息

会对目录中所有的内容生成差异输出,常用命令如:

$diff –Naur dir1 dir2

-N:将缺失的文件视为空文件;

-a:将所有文件视为文本文件;

-u:生成一体化输出;

-r:遍历目录下所有文件;

 

14,打印,head与tail命令

14.1 基本用法,都是例子:

head file                                        #打印前10行

head –n 4 file                              #打印前4行

head –n –4 file                            #打印除了最后4行的所有行(理解,最后一行为第0行,第一行为第-len行,

                                                       # 则此时打印第-len ~ -4行)

tail                                                  #打印最后10行

tail –n 5 file                                  #打印最后5行

tail –n +(N+1) file                        #打印除了前面N行的所有行(理解,从第N+1行开始)

 

head总是打印从头开始的内容;tail总是打印某行到末尾的内容;结合head与tai可打印固定的某些行,如: seq 1 100 | head –n 50| tail –n 20 将输出31~50;

 

14.2 tail的特殊用法

tail –f growing_file

-f参数,它使tail密切关注文件中新添加的内容;

如tail –f afile;另一边echo “Asdasd” >> afile,则tail的那个终端会相应的更新输出;默认1秒更新一次;

tail –f filename –s n,每n秒更新;

tail –f filename –pid PID,进程PID结束时,tail也接收跟踪filename;

--pid=PID

      with -f, terminate after process ID, PIDdies

 

另,涉及到一个命令pidof processname,pidof -- findthe process ID of a running program.

 

15,只列出目录的方法

本小节也是实践的例子,有以下几种只打印目录的方法:

1)ls –d */

接收,ls */,打印出匹配”*/”的文件,那将会是目录(因为以‘/’结尾);但ls dir将会打印出目录下的文件内容,而不是该目录名,所以此时加上-d参数,就将只打印该目录名而非目录下的内容;

例:dir1下有文件afile bfile,则,

$ ls dir1

afile  bfile

$ ls -d dir1

dir1

2)ls –F | grep “/$“

ls –F参数,会在输出项后面加上一个代表文件类型的字符,如* / @ 等,对应文件是*,对应目录是/ ;所以只要过来以/结尾的内容即可;

3)ls –l | grep “^d”

ls –l,打印出文件的详细信息,最前面将会代表文件类似的字符,在本章第6小节也说明了,这里不在详述;

4)find . –type d –maxdepth 1

这个在find命令的介绍中有(第2章第4节),也不在详述了;

 

注:不能用dir命令实现,dir -- list directory contents,即其功能是列出目录中内容,而不是目录;

 

16,pushd popd命令

以上两命令用在多个目录间进行切换,此时可以不再使用“cd + 相应路径名”的命令了;看例子来理解:

原本在目录/disk/test下,

1)pushd /disk/test/dir1

此时将/disk/test/dir1压入栈,此时栈内将有/disk/test/dir1 /disk/test两个目录成员;

继续压入几个目录后,我们查看目录栈内的内容,

2)dirs(注意区别上小节提到的dir与dirs)

$ dirs      #此时打印出栈内内容,我们给栈的内容将序号,如下

/disk/test/dir2/ddd   /disk/test/dir1/ddd   /disk/test/dir1       /disk/test

0                1                 2                 3

-3               -2                 -1                -0

现在我们在/disk/test/dir2/ddd目录下,要跳到/disk/test/dir1下,只需要执行:

3)$ pushd +2

/disk/test/dir1 /disk/test/disk/test/dir2/ddd /disk/test/dir1/ddd

$ pwd

/disk/test/dir1

即执行pushd +2,此时已切换到前面的2号目录下了;注意此时目录栈的内容也跟着旋转了!

另外,也可以执行pushd –n来切换目录,参考上面的负数序号;

4)从栈中删除路径

$ popd

这将会删除栈顶的路径,并切换到下一个目录

$ popd +no,则从列表中删除第no号目录,此序号的用法同上pushd+no(-no类似)

 

注意:实验发现,在用pushdpopd时,用cd去切换路径,会把栈顶的内容给替换掉,如下:

$ dirs

/disk/test /disk/test/dir2/ddd /disk/test/dir1/ddd/disk/test/dir1

$ pwd

/disk/test

$ cd dir1/ddd/

$ pwd

/disk/test/dir1/ddd

$ dirs

/disk/test/dir1/ddd /disk/test/dir2/ddd /disk/test/dir1/ddd/disk/test/dir1

 

5)还有一个,在两个目录下相互切换,大家都知道的“cd –”

 

17,统计文件行数、单词数、字符数

(如常用来统计代码行数LOC,line of code …)

wc 命令,word count

基本使用:

wc file,打印出file中的行数、单词数、字符数,如

$ wc tmp

1     1     14    tmp

wc –l file,仅打印出行数;

wc –w file,仅打印出单词数;

wc –c file,仅打印出字符数;

wc –L file,打印出file中最长行的长度;

 

17,打印目录树

tree命令,有时需要自己安装该工具;

1)直接使用tree命令即可:

$ tree

.

├── afile

├── bfile

└── ddd

    └── tmp

2)一些有用的参数:

tree path –P PATTERN #用通配符限定只打印相应的文件,如tree path –P “*.cpp”

tree path –I PATTERN #与-P相反,取某些样式之外的那些文件;

tree –h,同时打印文件和目录的大小;

tree path –H http://localhost –o out.html,可以生成一个html文件,该html文件展现了目录树的内容;

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《Linux Shell脚本攻略》 笔记 第三章:文件操作

《Linux Shell脚本攻略》 笔记 第三章:文件操作 1、生产任意大小的文件 [root@localhost dd_test]# [root@localhost dd_test]# dd i...

Linux shell脚本学习攻略笔记3

今天继续上一次find命令的内容,主要是find和 -exec 和xargs的结合和使用。      (9) find 命令可以借助选项-exec与其他命令进行结合。- exec算得上是find最强...
  • wwe4023
  • wwe4023
  • 2017年05月06日 12:38
  • 112

linux shell脚本攻略 学习笔记2 -- 第二章 命令之乐

linux shell脚本攻略第二章的学习记录。
  • hrl19
  • hrl19
  • 2015年06月30日 23:50
  • 319

linux shell脚本攻略 学习笔记1 -- 第一章 小试牛刀

针对着《linux shell脚本攻略》这本书进行shell学习,这本书似乎比较偏实际运用,并不是很系统,不过我觉得可能刚好适合我,我现在就需要实际的练习,遇到相关的问题再去查阅更系统的知识吧。 计划...
  • hrl19
  • hrl19
  • 2015年06月25日 20:40
  • 322

《Linux Shell脚本攻略》 笔记 第九章:进程管理

《Linux Shell脚本攻略》 笔记 第九章:进程管理 1、打印进程 [root@localhost program_test]# ps -e | head   PID TTY       ...

《Linux Shell脚本攻略》 笔记 第八章:磁盘、日志管理

《Linux Shell脚本攻略》 笔记 第八章:磁盘、日志管理 1、显示给定文件夹下的文件的磁盘适用情况 [root@localhost program_test]# du -a -h ./ 3...

《Linux Shell脚本攻略》 笔记 第二章:常用命令

《Linux Shell脚本攻略》 笔记 第二章:常用命令 1、cat      cat -s //多个空白行压缩成一个       cat *.txt | tr -s '\n'   //移除空白...

《Linux Shell脚本攻略》 笔记 第四章:高效文本处理

《Linux Shell脚本攻略》 笔记 第四章:高效文本处理 1、IP地址的正则表达式: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} 2、gre...

LINUX SHELL脚本攻略笔记[速查]

LINUX SHELL脚本攻略笔记[速查] Linux Shell脚本攻略笔记[速查] 资源shell scriptrun shell scriptechoprintf环境...
  • AresGod
  • AresGod
  • 2016年06月21日 17:33
  • 1682

Linux Shell脚本攻略学习总结:二

比较与测试程序中的流程控制是由比较和测试语句来处理的。我们可以用if,if else 以及逻辑运算符来执行测试,而用一些比较运算符来比较数据项。另外,有一个test 命令也可以用来进行测试。让我们来看...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux shell脚本攻略 学习笔记3 -- 第三章 以文件之名
举报原因:
原因补充:

(最多只允许输入30个字)