UNIX 的核心思想是有许多简单的命令可以通过管道和重定向链接在一起,以完成非常复杂的任务。请看以下示例。我只会解释最复杂的示例;对于其他示例,请学习以上章节和 man 手册。
问题: ls速度太快,文件名飞快闪过。
解决方案:
$ ls | less |
问题:我有一个包含单词列表的文件。我想反向排序并打印它。
解决方案:
$ cat myfile.txt | sort -r | lpr |
问题:我的数据文件有一些重复的行!我该如何摆脱它们?
解决方案:
$ sort datafile.dat | uniq > newfile.dat |
问题:我有一个名为 'mypaper.txt' 或 'mypaper.tex' 或类似的文件,但我不记得我把它放在哪里了。我该如何找到它?
解决方案:
$ find ~ -name "mypaper*" |
解释find是一个非常有用的命令,可以列出目录树中的所有文件(从~在这种情况下)。它的输出可以被过滤以满足几个标准,例如-name.
问题:我在此目录中有一个包含单词 'entropy' 的文本文件,有什么类似SEARCH?
解决方案:是的,试试
$ grep -l 'entropy' * |
问题:在某处我有包含单词 'entropy' 的文本文件,我想知道是哪些以及它们在哪里。在 VMS 下我会使用search entropy [...]*.*;*,但是grep无法递归子目录。现在怎么办?
解决方案:
$ find . -exec grep -l "entropy" {} \; 2> /dev/null |
解释find .输出从当前目录开始的所有文件名,-exec grep -l "entropy"是要在每个文件上执行的操作(由{}), \终止命令。如果你认为这种语法很糟糕,你是对的。
作为替代方案,编写以下脚本
#!/bin/sh # rgrep: recursive grep if [ $# != 3 ] then echo "Usage: rgrep --switches 'pattern' 'directory'" exit 1 fi find $3 -name "*" -exec grep $1 $2 {} \; 2> /dev/null |
解释grep像search一样工作,并将其与find我们兼得两者之长。
问题:我有一个数据文件,它有两行标题行,然后每行有 'n' 个数据,不一定均匀分布。我想要每行的第 2 个和第 5 个数据值。我应该写一个 Fortran 程序吗...?
解决方案:不用。这样做更快
$ awk 'NL > 2 {print $2, "\t", $5}' datafile.dat > newfile.dat |
解释:命令awk实际上是一种编程语言:对于从第三行开始的每一行,在datafile.dat,打印出第二个和第五个字段,用制表符分隔。学习一些awk---它可以节省大量时间。
问题:我下载了一个 FTP 站点的ls-lR.gz以检查其内容。对于每个子目录,它都包含一行写着 "total xxxx",其中 xxxx 是目录内容的大小(千字节)。我想获得所有这些 xxxx 值的总和。
解决方案:
$ zcat ls-lR.gz | awk ' $1 == "total" { i += $2 } END {print i}' |
解释zcat输出.gz文件的内容并通过管道传输到awk,请您阅读其 man 手册 ;-)
问题:我编写了一个 Fortran 程序,myprog,用于从数据文件中计算一个参数。我想在数百个数据文件上运行它并获得结果列表,但每次都询问文件名很麻烦。在 VMS 下我会编写一个冗长的命令文件,在 Linux 下呢?
解决方案:一个非常短的脚本。让你的程序查找数据文件 'mydata.dat' 并在屏幕 (stdout) 上打印结果,然后编写以下脚本
#!/bin/sh # myprog.sh: run the same command on many different files # usage: myprog.sh *.dat for file in $* # for all parameters (e.g. *.dat) do # append the file name to result.dat echo -n "${file}: " >> results.dat # copy current argument to mydata.dat, run myprog # and append the output to results.dat cp ${file} mydata.dat ; myprog >> results.dat done |
问题:我想在我所有的文本文件中将 `geology' 替换为 `geophysics'。我应该手动编辑它们吗?
解决方案:不用。编写这个 shell 脚本
#!/bin/sh # replace $1 with $2 in $* # usage: replace "old-pattern" "new-pattern" file [file...] OLD=$1 # first parameter of the script NEW=$2 # second parameter shift ; shift # discard the first 2 parameters: the next are the file names for file in $* # for all files given as parameters do # replace every occurrence of OLD with NEW, save on a temporary file sed "s/$OLD/$NEW/g" ${file} > ${file}.new # rename the temporary file as the original file /bin/mv ${file}.new ${file} done |
问题:我有一些数据文件,我不知道它们的长度,必须删除它们倒数第二行和倒数第三行。呃... 手动吗?
解决方案:不,当然不是。编写这个脚本
#!/bin/sh # prune.sh: removes n-1th and n-2th lines from files # usage: prune.sh file [file...] for file in $* # for every parameter do LINES=`wc -l $file | awk '{print $1}'` # number of lines in file LINES=`expr $LINES - 3` # LINES = LINES - 3 head -n $LINES $file > $file.new # output first LINES lines tail -n 1 $file >> $file.new # append last line done |
我希望这些例子引起了您的兴趣...