第三章 以文件之名生成任意大小的文件$ dd if=/dev/zero of=junk.data bs=1M count=1记录了1+0 的读入记录了1+0 的写出1048576字节(1.0 MB)已复制,0.735955 秒,1.4 MB/秒查找并删除重复文件条件:删除那些虽然名字不同但内容一模一样的文件通过文件内容来识别他们,校验和是依据文件内容来计算的,内容相同的文件自然就生成想通的校验和通过比较校验和来删除重复文件书本代码有误,补充如下
#!/bin/bashls -lS | awk 'BEGIN{getline;getline;name1=$9;size=$5}{name2=$9;if (size==$5){"md5sum $name1" | getline;csum1=$1;"md5sum $name2" | getline;csum2=$1;if (csum1==csum2){print name1;print name2;}};size=$5;name1=name2;}' | sort -u > duplicate_filescat duplicate_files | xargs -I {} md5sum {} | sort | uniq -w 32 | awk '{ print $2 }' | sort -u > duplicate_sampleecho Removing..comm duplicate_files duplicate_sample -2 -3 | tee /dev/stderr | xargs rm -fecho Removed duplicates files successfully.rm duplicate_sample duplicate_files
以不同的用户运行可执行文件原理:有一个叫做setuid的特殊文件权限,它允许其他用户以文件所有者的身份来执行文件chown root.root execu_filechown +s execu_file./execu_file这个文件事实上每次以超级用户来运行setuid的使用不是无限制的,它只能应用在linux ELFG格式二进制文件上,二不能用于脚本创建文件不可修改限制:一旦文件呗设置为不可修改,任意用户包括超级用户都不能删除文件,除非其不可修改的属性被移除通过查看/etc/mtab文件,很容易找出所有挂载分区的文件系统类型 cat /etc/mtab/dev/sda1 / ext4 rw,errors=remount-ro 0 0proc /proc proc rw,noexec,nosuid,nodev 0 0sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0none /sys/fs/cgroup tmpfs rw 0 0none /sys/fs/fuse/connections fusectl rw 0 0none /sys/kernel/debug debugfs rw 0 0none /sys/kernel/security securityfs rw 0 0udev /dev devtmpfs rw,mode=0755 0 0devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=0620 0 0tmpfs /run tmpfs rw,noexec,nosuid,size=10%,mode=0755 0 0none /run/lock tmpfs rw,noexec,nosuid,nodev,size=5242880 0 0none /run/shm tmpfs rw,nosuid,nodev 0 0none /run/user tmpfs rw,noexec,nosuid,nodev,size=104857600,mode=0755 0 0binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,noexec,nosuid,nodev 0 0gvfsd-fuse /run/user/zhangjianlin/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,user=zhangjianlin 0 0可以用chattr将文件设置为不可修改实战演练将一个文件设置为不可修改chattr +i file或者sudo chattr +i filerm file出错移除不可修改的属性chattr -i file修改文件三个时间touch -a 更文件访问时间touch -m 更改文件内容修改时间touch -d 时间戳列举文件夹下的类型统计信息file -b filenameASXII text脚本如下
#!/bin/bashif [ $# -ne 1 ];then echo $0 basepath; echofipath=$1declare -A statarraywhile read line;do ftype=`file -b "$line"` let statarray["$ftype"]++; done< <(find $path -type f -print) echo ========file types and counts==========for ftype in "${!statarray[@]}";do echo $ftype : ${statarray["$ftype"]}done
结果$ bash filestat.sh .========file types and counts==========Bourne-Again shell script, ASCII text executable : 2empty : 2原理while read linedo echo $linedone<A <A写在最后相当于给整个while do 语句加了一个约束条件,读取文件A里每行至文件尾结束while read line<Ado echo $linedone<A写在前面,整个while do语句就没有约束条件, 因为 read line<A这个始终为真表示 不停地 读取A中的第一行,赋值给参数line,然后打印参数line的值.done< <(find $path -type f -print) <(find $path -type f -print) 等同与文件名。只不过他用子进程输出代替文件名${!statarray[@]} 用于返回一个数组索引列表
第四章。让文本飞正则表达式入门更多内容百度匹配一个ip地址[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}grep搜索文本扩展内容递归搜索包含词的文件grep "text" . -R -n #开发人员常用的命令如$ grep "bin" . -R -n ./第三章:42:binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,noexec,nosuid,nodev 0 0./第三章:66:#!/bin/bash./second/mvsuffix.sh:1:#!/bin/bash./second/mvfilename.sh:1:#a!/bin/bash./touchlearnfiles.sh:1:#!/bin/bash./第一章.txt:25:#!/bin/bash./第一章.txt:36:#!/bin/bash./第一章.txt:45:#!/bin/bash./第一章.txt:71:#!/bin/bash./第一章.txt:74:(cd /bin; ls);./第一章.txt:97:#!/bin/bash./第一章.txt:117:#!/bash/bin./第一章.txt:133:line="root:x:0:0:root:root:/bin/bash"./第一章.txt:178:#!/bin/bash./first/password.sh:1:#!/bin/bash./first/dealpasswd.sh:1:#!/bash/bin./first/dealpasswd.sh:17:line="root:x:0:0:root:root:/bin/bash"./first/IFSofdiv.sh:1:#!/bin/bash./first/array_var.sh:1:#!/bin/bash./first/cilldshell.sh:1:#!/bin/bash./first/cilldshell.sh:4:(cd /bin; ls);./first/delaysleep.sh:1:#!/bin/bash./first/filetest.sh:1:#!/bin/bash./第二章.txt:160:#a!/bin/bash./第二章.txt:196:#!/bin/bash./third/filestat.sh:1:#!/bin/bash./third/remove_duplicates.sh:1:#!/bin/bash在grep 搜索中包括或排除文件只在目录中递归搜索所有的.c .cpp文件:$ grep "main()" . -r --include *.{c,cpp}搜索中排除所有的README文件$ grep "main()" . -r --exclude "README"
对文件中的行、单词和字符进行迭代实战迭代文件中的每一行while read line;echo $line;done < file.txt每一行的单词for word in $linedoecho $word ;done迭代一个单词中方的每一个字符for ((i=0;i<${#word};i++))doecho${word:i:1};done${word:start_position:no_of_characters} 返回变量word所包含的字符串中的一个字窜 :重要cat touchlearnfiles.sh | (while read line; do echo $line; done)
结果:
#!/bin/basharrays=("一" "二" "三" "四" "五" "六" "七" "八" "九" "十")arraynums=(first second third fourth fifth sixth seventh eighth ninth tenth)read -p "please input the number of caption:" num;touch "第${arrays[$num-1]}章.txt"mkdir ${arraynums[$num-1]}awk打印多列数据,并在列间插入指定的字符$ ls -l | awk '{ print $1" : " $8 }' 实战演练:打印不同行或样式之间的文本打印从第M行到N行这个范围内的所有文本,使用下面语法:$ awk 'NR==M, NR==N' filename把M跟N换成数字$ seq 100 | awk 'NR==4, NR==6'要打印处于'/start_pattern/,/end_pattern/' filename 如$ cat section.txtline with pattern1line with pattern2line with pattern3line end with pattern4line with pattern5$awk '/pa.*3/, /end/' sectionline with pattern3line end with pattern4回文判断 最简单的使用命令rev命令rev 接受一个文件或stdin作为输入,并逆序打印每一行内容试试下面的代码
#/bin/bahstring="malayalam"if [[ "$string" == "$(echo $string | rev )" ]]; #重点thenecho "Palindrome"elseecho "not palindrome"fi
解析文本中的点子邮件地址和url解析emailegrep -o '[A-Za-z0-9.]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}'匹配HTTP URL的正则表达式egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-A]{2,3}"http://www.google.comhttp://code.google.com原理[a-zA-Z0-9.]+ “+”表示应该出现多次用awk实现head、tail和tac实战演练$ awk 'NR <=10' filename模拟tail命令打印文件的后10行$ awk '{ buffer[NR % 10] = $0;} END { for(i=1;i<11;i++){print buffur[i%10] } }' filename文件切片与参数操作替换变量内容中的部分文本$ var="this is a line of text"$ echo ${var/line/REPLACED}"This is a REPLACED of text"$name ${name%$1}$2 #${name%\.*} "%"号除去后缀名,只取文件名${file_name#*.} 只留扩展名或后缀生成子窜${variable_name:start_positon:length}最后一个字符索引记为-1,使用负数索引的话,必须将负数放入括号内,例如(-1)就是最后一个字符的索引如 string={a..z}echo ${string:(-2):2}yz