Shell脚本学习-文件操作和文本处理

时间:2022-12-20 13:09:14

Solaris下文件操作和文本处理相关shell整理。

$ls
    -a: all entries; -A: all entries, with the exception of . and ..
    -l: long format; -e:same as -l, 显示时间到秒;  -E: same as -l, 显示时间到纳秒
    -L: 列出symbolic link所指向的实际文件(夹)的属性,但是文件名还是symbolic link的名字,可以和-l一起使用;
    -p: put a slash(/) after each file name if the file is a directory;
    -d: 显示目录本身信息而不是包含的文件的信息; -R 递归到每个子目录
    -t: Sorts by time stamp (latest first); -r: Reverses the order of sort;
    -h: human readable format for file size, xxxK, xxxM, xxxG;
    -v verbose ACL: -l输出再加上详细ACL信息
    -i: 输出inode信息
*默认使用最后修改时间来排序(-t)或者输出列表(-l|-e);
*-u 使用last access time;
*-c 使用i节点文件状态的最后修改时间;
*上述三种时间(access,modification,status change)分别对应st_atime,st_mtime,st_ctime

$touch file, 更新上述三种时间为当前时间;
    -m只更新最后修改时间和状态最后修改时间;
    -a 只更新最后访问时间;
    可以指定一个时间;
         -d YYYY-MM-DDThh:mm:SS[.frac][tz] T为字符T或者空格[,frac]也可;
         -t [[CC]YY]MMDDhhmm[.SS]

$find path-list predicate-list:在指定路径查找.
    例如find .或者find *列出当前目录下的所有文件;find dir列出dir目录下的所有文件。
    -name <pattern>: 查找指定文件。pattern可以包含通配符但是需要加上引号,例如find . -name "aa*"
    -ls,列出查找到文件的属性;,例如find . -name b -ls。
    -exec,执行命令,例如find . -name b -exec rm {} \; ({}代表当前文件路径,用\;分割命令)
    -ok, 同-exec,更安全,执行命令之前要求用户确认
    -type [dfl],指定文件类型,d-directory,f-file,l-link
    -prune,不递归处理子目录,例如 find * -prune -type d 找出当前目录下的所有文件夹
    -o=OR, [-a]=AND可省略,例如find . -name a -o -name b
    ! 对某个表达式取反,例如 find * -prune ! -type d 找出当前目录下的所有不是文件夹的文件
    -size [+-]n[c] 按文件大小查找,+表示大于,-表示小于;c表示字节数,不加c表示block-512字节
    {-ctime|-mtime|-atime} [+-]n n天前状态修改/内容修改/访问过的文件
    -newer timstampfile 比timestampfile修改时间更近的文件

*ls和find命令都可以使用通配符
    ? 匹配任何1个字符  * 匹配任何字符或字符串
    [set] 匹配任何在set中的字符,可指定范围,例如0-9,a-z
    [!set] 匹配任何不在set中的字符
 
$/usr/bin/grep expression filelist: 在文件内容中查找.-v输出不包括expression的行;-i不分大小写;-n输出行号
    expression为BRE(basic regular expression)基本正则表达式,例如 grep -v "^$" file 过滤空行。
    如果是正则表达式,最好给expression加上引号,例如grep "\\<se" file 查找包含se开头的单词的行。
$/usr/xpg4/bin/grep -E "ab|ad" filelist: -E选项支持ERE(extended regular expression).包含ab或者ad.
    XPG4-X/Open Portability Guide, Fourth Edition; XPG5-即UNIX98或称Single UNIX Specification.
$/usr/bin/egrep 支持ERE.
[:alpha:] 英文字母
[:alnum:] 英文字母和数字
[:digit:] 数字
[:xdigit:]16进制数字
[:blank:] 空格和tab
[:graph:] 非空格字符
[:space:] 空白字符,包括换行
[:cntrl:] 控制字符
[:lower:] 小写
[:upper:] 大写
[:print:] 可显示字符
[:punct:] 标点符号
*以上在正则表达式里面使用时需要放到方括号中.
*[:alpha:]表示匹配字母a,l,p,h,:  表示匹配英文字母的写法是[[:alpha:]]

$file: determine file type,可察看32bit/64bit程序等。
$wc file: 统计文件。-l 行数; -w 字数; -c 字符数。 
$tail -f file: 跟踪文件内容变化。+n, 文件第n行开始的内容; -n, 文件最后n行的内容
$head -n file: 显示头n行的内容。
$cat file: 把文件内容打印到标准输出
    $cat >file: 把标准输入内容写入文件。以ctrl+d结束输入。
    $cat file1 file2 > file3: 把file1和file2的内容合并到file3。
$od [-cx] [file]:octal dump. -x: HEX output; -c: character output.
$fmt file: 格式化文件, -w 指定每行字符宽度,默认为72字符; -s 只分割长行不合并短行,
    例如 sed -n '1,20p' /usr/dict/words | fmt -w 30
$tee file: 拷贝stdout输出到文件. -a 追加到文件末尾.

$dd: 拷贝并转换文件。
   if=输入文件;of=输出文件;bs=n指定block大小;skip=n忽略n输入block;count=n只拷贝n输入block;
   conv=lcase/ucase转换大小写
   例:忽略头1k,拷贝trace.log文件1k内容到conv.log并转换为大写
        dd if=trace.log of=conv.log bs=1024 skip=1 count=1 conv=ucase

$tr string1 string2: 读取stdin,把string1中的每一个字符转换为string2中对应的字符,
    例如 tr abc def < file 把文件中所有字符,a->d,b->e,c->f。
    tr [:lower:] [:upper:] < file 把文件中所有字符从小写转为大写。
    tr -d[c] string1 删除string1。-c complement,取补集,即删除除了string1以外的内容。
    [c-c]指定字符范围;
    [x*n],只可用在string2中,表示n个字符x,如果n省略或者为0,表示n等于string1的长度
    -s 删除连续出现字符为1个;
        例如tr -cs "[a-z]'[A-Z]" "[\n*]" < file,输出文件file中的单词列表,每行一个.
*关于回车(carriage return)换行(line feed),
*Window下用回车换行\r\n(0D0A)来表示,linux下是换行\n(0A)来表示。
*Window上的文件拷到unix上用时,每行后面会多个^M。
*可以用 cat file | tr -d "\r" > newfile 来删除file中的\r。

$sed [-n] [-e script]... [-f scriptfile]... [file]... 流编辑器Stream Editor,
    从文件读入,应用指定编辑命令,结果输出到stdout.
    如果只有1个编辑命令,-e可省略,支持正则表达式,
        例 sed 's/:.*//' /etc/passwd (s命令用来查找替换)删除第一个:后的所有内容.
        例 sed '/[0-9]/d' file, (d命令表示删除)删除包含数字的行;
        例 sed 's/^/#/' file, 给file的所有行前面加上#.
    -n不输出结果,除非在脚本里明确使用p,
        例 sed -n 's/df/DF/gp' file, 只输出被替换过的行(g表示全局替换,否则只替换第一个)
    如果使用一个脚本文件,可以使用特殊的行首,例如使用下面的脚本sed.script,
        sed -e 's/df/DF/g' -f sed.script file, 只输出包含123456的行。
              #n
              /123456/p
    &符号表示匹配表达式的整个文本。例如 sed 's/df/&DF/g' file, 把所有df替换为dfDF.
    可以给匹配表达式加上限定范围,例如 sed '/a[ab]/ s/df/DF/g' file, 在包含aa或者ab的行中替换.
    可以指定一个范围,例如 sed '/^12/,/^45/ s/df/DF/g' file,  从12开头到45开头的行中f替换.
    可以用数字表示行号, $符号表示最后一行, 例如 sed -n '5,$p' file 表示从第5行开始打印到最后一行.
    可以在匹配表达式前加上!表示限定范围以外,
        例如  sed '/a[ab]/ !s/df/&DF/g' file, 在不包含aa或者ab的行中,把所有df替换为dfDF.
    可以使用/以外的界定符,例如 sed 's;/home/export/;/home/export/oracle/;g' file 这里用;作为界定符.

$cmp file1 file2: 比较2个文件,如果相同不输出任何信息,否则输出第一个不同位置到stdout;
    -s 不输出任何信息.如果相同返回值0.
$diff file1 file2: 比较2个文件。- i 忽略大小写; -b 忽略行尾的空格和制表符; -w忽略所有空格和制表符;
$dircmp dir1 dir2: 比较2个目录。-s 不输出相同文件信息; -d 使用diff比较两个目录中都存在的文件内容。
$split -l 1000 file name: 分割文件file,分割后文件每个1000行,前缀name;
    -b 1024, 每个文件1024byte; -b 1024k, 每个文件1024K.
$paste file1 file2: 逐行合并,把第二个文件第一行粘贴到第一个文件第一行后面,依此类推,结果输出到stdout

$cut -d : -f 1,5 /etc/passwd: 选定输出字段;-d 指定分隔符delimiter,默认为tab;
    -f指定字段,-c指定字符, 2者都可以指定多个值(逗号分开),也可以指定范围m-[n],n省略表示到最后
$sort file: 对文件每行进行排序输出到stdout.
    -o outfile 输出到文件;
    -f 忽略大小写; -r 反序; -n 按照数字(numeric)排序
    -m merge files. 文件需要事先排序好。例如sort -mn -o merge.sorted 1.sorted 2.sorted
    -kx 按照第x个字段排序; -t char 以char为字段分隔符,默认为空白字符;
    -b 忽略排序字段开头的空白(和-k配合使用), 例如sort -t: -k3nrb /etc/passwd 按照UID降序
    可以指定多个字段排序,例如 sort -t: -k4nb -k3nb /etc/passwd 先按照GID,再按照UID排序
$uniq [-c|-d|-u] file: 清除排序后文件中的重复记录;
    -c 在记录前显示计数; -d 仅显示重复记录; -u 仅显示未重复记录,
        例如 cut -d: -f4 /etc/passwd | sort -n |uniq -c
$comm file1 file2: select common lines in 2 files.
    两个文件需要事先排序,输出只在文件1存在的行,只在文件2存在的行,2个文件中都存在的行
$join -j1 1 -j2 1 -t : passwd.1 passwd.2: 按照关键字合并2个排好序的文件,
    -j1 -j2分别指定2个文件中关键字段的位置,默认都为1;-t指定输入文件的分隔符,也作为输出的分隔符;

$chmod 777 file: 增加owner, group, other的所有权限(x, w, r; 1->execute; 2->write; 4->read)
    chmod [ugoa]{+|-|=}{rwx} file: u->user; g->group; o->other; a->all;不指定为a。例:chmod go+rw file
    -R递归操作文件夹; -f force mode
$chown -R owner[:group] file...: 改变文件owner,-R递归操作文件夹
$umask [mask]: 显示设置限制新文件权限的掩码; 例如022, g和o的w位不可用, 即u=rwx,g=rx,o=rx
    -S: symbolic output.
$mkdir -p directories: 创建目录,包括不存在的parent directory。
$rm -rf dirname: 删除目录
    -r=Recursively, -f=Removes all files (whether write-protected or not)
$cp source_file target_file/cp source_file target_dir
    cp -r: Recursive, 拷贝目录
    cp -p: Preserve, 保留文件修改时间,ACL等属性。
    cp -P: Preserve(大写P), 保留symbolic links。不加此选项则拷贝link指向的文件。
$mv source_file target_file
    mv source_file target_dir
    mv source_dir target_dir
$ln -s source target: create a symbolic link。注意source要使用全路径。

$tar
    c Create,创建档案文件
    r Replace,添加文件到档案文件末尾
    u Update,更新档案文件中的文件,
        如果不存在或者此文件添加到档案文件后又被更新过,则添加到档案文件末尾。
    t Table of Contents, 列出档案中的内容。
    x Extract, 释放文件。
    f File, 指定tarFile参数。
    v Verbose
        $tar cvf|rvf|uvf tarFile file
        $tar tvf tarFile
        $tar xvf tarFile

$gzip [-v] file: 压缩文件file->file.gz,并删除原始文件file。-v输出压缩比。
    $gzip -cv file 〉xxx.gz: 保留原始文件file并输出压缩结果到stdout。
    $gzip -l xxx.gz: list压缩前后size, 压缩比,原始文件名字。
    $gzip -d xxx.gz: decompress
    $gzip -cdv xxx.gz > file: decompress, 保留原始文件xxx.gz。

*常见脚本起始部分对临时文件的处理:
    先删除其他人的所有权限;产生临时文件名,如果存在环境变量TMPDIR,则用它代替/tmp,
    $$代表进程ID;trap语句在退出时删除临时文件。
        umask 077
        TMPFILE=${TMPDIR-/tmp}/myprog.$$
        trap 'rm -f $TMPFILE' EXIT
    可以用mktemp命令产生临时文件。
        TMPFILE=`mktemp` 如果存在环境变量TMPDIR,在这个目录下生成临时文件。
    可以为mktemp指定一个模板TMPFILE=`mktemp /tmp/myprog.XXXXXX`, XXXXXX部分会被替换。
   指定-d选项生成临时文件夹。