当前位置: 首页 > 科技观察

搞定 Linux Shell 文本处理工具,看完这篇还不够

时间:2023-03-18 22:59:43 科技观察

搞定LinuxShell文本处理工具,看这篇文章还不够,awk;提供的示例和参数是最常用和最实用的;使用shell脚本的原则是单行写命令,尽量不要超过2行;如果你有更复杂的任务需求,可以考虑python。1.find文件搜索查找txt和pdf文件find.(-name"*.txt"-o-name"*.pdf")-print正则方式查找.txt和pdffind.-regex".*(.txt|.pdf)$"#-iregex:regularnegationignoringcase-typefcustomsearch#Searchbytype:find.-typed-print//只列出所有目录#Searchbytime:-atime访问时间(单位是天,分钟单位是-amin,下同)-mtime修改时间(内容被修改)-ctime修改时间(元数据或权限修改)最近7天访问过的所有文件:find.-atime7-typef-print#Search按大小:查找大于2k的文件find.-typef-size+2k#按权限查找:find.-typef-perm644-print//查找所有具有可执行权限的文件#按用户查找:find.-typef-userweber-print//查找用户weber拥有的文件后续操作删除:#删除当前目录下的所有swp文件:find.-typef-name"*.swp"-delete#执行操作(强大的exec)find.-typef-userroot-execchownweber{};//当前改变目录的所有权为weber注:{}是一个特殊的字符串,对于每一个匹配的文件,{}都会被替换成对应的文件名;例如:将找到的所有文件复制到另一个目录:find.-typef-mtime+10-name"*.txt"-exe共产党{}老;组合多条命令提示:如果需要执行多条命令,可以将多条命令写成一个脚本,调用-exec时执行该脚本;-exec./commands.sh{};#-print的分隔符默认使用''作为文件的分隔符;-print0使用''作为文件的分隔符,这样可以搜索包含空格的文件;2.greptextsearchgrepmatch_pattenfile//默认访问匹配的行常用参数:-o只输出匹配的文本行VS-v只输出不匹配的文本行-c统计文件中包含的文本行数grep-c"text"filenamen打印匹配行号i搜索时忽略大小写l只打印文件名递归搜索多级目录中的文本(程序员最喜欢的代码搜索):grep"class"。-R-n匹配多个模式grep-e"class"-e"vitural"filegrep输出结尾为字符的文件名:(-z)grep"test"file*-lZ|xargs-0rmxargs命令行参数转换xargs可以将输入数据转换成特定命令的命令行参数;这样,它可以与许多命令结合使用。比如grep,比如find;将多行输出转为单行输出catfile.txt|xargs为多行文本之间的分隔符将单行转为多行输出catsingle.txt|xargs-n3#-n:指定每一行显示的个数fieldsxargs参数说明-d定义分隔符(多行分隔符默认为空格)-n指定输出为多行-I{}指定替换字符串,xargs展开时会替换掉,当命令到执行需要多个参数catfile.txt|xargs-I{}./command.sh-p{}-1#-0:指定为输入分隔符#statisticalprogramlinenumberfindsource_dir/-typef-name"*.cpp"-print0|xargs-0wc-l3,sort排序字段说明:-n按数字排序VS-d按字典序排序-r逆序排序-kN指定按第N列排序sort-nrk1data.txtsort-bddata//ignoreleadingblankcharacterslikespaces4.uniq消除重复行消除重复行sortunsort.txt|uniqc统计每行在文件中出现的次数sortunsort.txt|uniq-c查找重复行sortunsort.txt|uniq-d可以指定每行需要比较的重复内容:-s起始位置-w比较字符数5,用tr转换一般用法echo12345|tr'0-9''9876543210'//加解密转换,替换对应字符cattext|tr''''//tab转空格tr删除字符catfile|tr-d'0-9'//删除所有数字-ccomplementsetcatfile|tr-c'0-9'//获取文件catfile|tr-d-c'0-9'//删除非-numericdatatrcompressedcharacterstr-s压缩文本中出现的重复字符;最常用于压缩冗余空格catfile|tr-s''字符类:tr中可用的各种字符类alnum:字母和数字alpha:字母digit:数字space:空白字符lower:小写upper:大写cntrl:控制(非printable)charactersprint:printable字符使用方法:tr[:class:][:class:]eg:tr'[:lower:]''[:upper:]'6,cut按列拆分文本#截取文件的第二列和第四列:cut-f2,4filename#删除文件除第三列以外的所有列:cut-f3--complementfilename#-d指定分隔符:cat-f2-d";"filenamecut的范围是N-第N个字段到结尾-M第一个字段是MN-MN到M个字段的切割单位是-b字节asunit-cascharacterunit-fasfieldunit(使用定界符cut-c1-5file//打印前5个字符cut-c-2file//打印前2个字符7,paste按列拼接文本拼接两个文本togetherbycolumnscatfile112catfile2colinbookpastefile1file21colin2book默认分隔符是制表符,可以用-d指定分隔符pastefile1file2-d","1,colin2,book8,wc统计行数和字符数的工具wc-lfile//统计行数wc-wfile//统计字数wc-cfile//统计字符数9、sed文本替换利器替换seg的/te的第一部分xt/replace_text/'file//替换每行的第一部分全局替??换seg's/text/replace_text/g'文件中的匹配文本默认被替换,并输出替换后的内容。如果需要直接替换原文件,使用-i:seg-i's/text/replace_text/g'file去掉空行:sed'/^$/d'filevariableconvertsmatchedstringstoreferencesbytoken&。echothisisenexample|seg's/w+/[&]/g'$>[this][is][en][example]子串匹配标记第一个匹配的括号内容使用标记引用sed's/hello([0-9])//'双引号求值sed通常用单引号引起来;也可以使用双引号,在双引号之后,双引号会计算表达式:sed's/$var/HLLOE/'使用双引号时,我们可以在sed模式和替换字符串中指定变量;p=pattenr=replacedecho"lineconapatten"|sed"s/$p/$r/g"$>lineconareplaced字符串插入字符:将每行文本(PEKSHA)转换为PEK/SHASed的/^.{3}/&//g'file10、awk数据流处理工具awk脚本结构awk'BEGIN{statements}statements2END{statements}'工作方式1.执行begin中的语句块;2.从文件或stdin中读取一行,然后执行statements2,重复此过程,直到读取完所有文件;3.执行end语句blockprint打印当前行,使用不带参数的print时,会打印当前行;echo-e"line1line2"|awk'BEGIN{print"start"}{print}END{print"End"}'#当print用逗号分隔,参数用空格分隔;echo|awk'{var1="v1";var2="V2";var3="v3";printvar1,var2,var3;}'$>v1V2v3#use-拼接字符(""为拼接字符);echo|awk'{var1="v1";var2="V2";var3="v3";printvar1"-"var2"-"var3;}'$>v1-V2-v3特殊变量:NRNF01$2NR:表示记录条数,对应执行时的当前行号名词;NF:表示字段数,执行时始终对应当前行的字段数;$0:该变量包含了执行过程中的字段数当前行的文本内容;$1:第一个字段的文本内容;$2:第二个字段的文本内容echo-e"line1f2f3line2line3"|awk'{printNR":"$0"-"$1"-"$2}'#打印每一行的第二个和第三个字段awk'{print$2,$3}'file#统计文件行数:awk'END{printNR}'file#累加每一行的第一个字段:echo-e"1234"|awk'BEGIN{num=0;print"begin";}{sum+=$1;}END{print"==";printsum}'#通过外部变量var=1000echo|awk'{printvara}'vara=$var#Inputcomesfromstdinawk'{printvara}'vara=$varfile#InputcomesfromfileFilterlinesprocessedbyawkwithstyleawk'NR<5'#的行号小于5awk'NR==1,NR==4{print}'file#打印等于1和4的行号awk'/linux/'#包含linux文本的行(可以指定通过正则表达式,超级强大)awk'!/linux/'#为不包含linux文本的行设置分隔符使用-F设置分隔符(默认为空格)awk-F:'{print$NF}'/etc/passwdread取出命令输出,使用getline将外部shell命令的输出读入变量cmdout;echo|awk'{"greproot/etc/passwd"|getlinecmdout;printcmdout}'使用循环for(i=0;i<10;i++){print$i;}for(iinarray){printarray[i];}以相反的顺序打印行:(tac命令的实现)seq9|awk'{lifo[NR]=$0;lno=NR}END{for(;lno>-1;lno--){printlifo[lno];}}'awk实现head和tail命令head:awk'NR<=10{print}'filenametail:awk'{buffer[NR%10]=$0;}END{for(i=0;i<11;i++){printbuffer[i%10]}}'filename打印指定列#awk实现:ls-lrt|awk'{print$6}'#cut方式实现ls-lrt|cut-f6打印指定文本区域#determinelinenumberseq100|awk'NR==4,NR==6{print}'#determinethetext打印startpattern和endpattern之间的文本;awk'/start_pattern/,/end_pattern/'filenameseq100|awk'/13/,/15/'cat/etc/passwd|awk'/mai.*mail/,/news.*news/'awk常用内置函数index(string,search_string):返回search_string在字符串中出现的位置sub(regex,replacement_str,string):将正则表达式匹配到的第一个内容替换为replacement_str;match(regex,string):检查正则表达式是否可以匹配字符串;length(string):returnstringlengthecho|awk'{"greproot/etc/passwd"|getlinecmdout;printlength(cmdout)}'#printf类似于c语言中的printf,格式化输出seq10|awk'{printf"->%4s",$1}'#遍历文件中的行、词、字符1.遍历文件中的每一行while循环方法whilereadline;doecho$line;done(whilereadline;doecho$line;done)awk方法:catfile.txt|awk'{print}'2。迭代一行中的每个单词forwordin$line;doecho$word;done3。遍历每个字符{#word}:返回变量word的长度for((i=0;i<${#word};i++))doecho${word:i:1);done