基本命令
ls
: "列出"文件的基本命令. 但是往往就是因为这个命令太简单, 所以我们总是低估它. 比如, 使用-R选项, 递归选项,
ls将会以目录树的形式列出所有文件. 另一个很有用的选项-S, 将会按照文件尺寸列出所有文件, -t, 将会按照修改时间来列出文件,
-i选项会显示文件的inode。
cat, tac
: cat, 是单词concatenate的缩写, 把文件的内容输出到stdout. 当与重定向操作符(>或>>),
一般都是用来将多个文件连接起来.
cat命令的-n选项是为了在目标文件中的所有行前边插入行号.
-b也是用来加行号的, 但是不对空行进行编号. -v选项可以使用^标记法来echo出不可打印字符. -s选项可以把多个空行压缩成一个空行.
在一个管道中, 有一种把stdin重定向到一个文件中更有效的方法,
这种方法比使用cat文件的方法更高效.
cat filename | tr a-z A-Z
tr a-z A-Z < filename # 效果相同,
但是处理更少,并且连管道都省掉了
tac命令, 就是cat命令的反转,
这个命令将会从文件结尾部分列出文件的内容.反向cat。
rev
: 把每一行中的内容反转, 并且输出到stdout上. 这个命令与tac命令的效果是不同的, 因为它并不反转行序,
而是把每行的内容反转.
cp
: 这是文件拷贝命令. cp file1 file2把文件file1拷贝到file2, 如果file2存在的话,
那么file2将被覆盖。 特别有用的选项就是-a选项, 这是归档标志(目的是为了copy一个完整的目录树), -u是更新选项,
-r和-R选项是递归标志.
cp -u source_dir/*
dest_dir #
把源目录"同步"到目标目录上, 也就是拷贝所有更新的文件和之前不存在的文件.
mv
: 这是文件移动命令. 它等价于cp和rm命令的组合. 它可以把多个文件移动到目录中,甚 至将目录重命名.当使用非交互脚本时,
可以使用mv的-f(强制)选项来避免用户的输入.当一个目录被移动到一个已存在的目录时, 那么它将成为目标目录的子目录.
rm
: 删除(清除)一个或多个文件. -f选项将强制删除文件, 即使这个文件是只读的. 并且可以用来避免用户输入(在非交互脚本中使用).
当使用递归参数-r时, 这个命令将会删除整个目录树. 如果不慎的使用rm -rf *的话, 那整个目录树就真的完了.
rm将无法删除以破折号开头的文件.解决这个问题的一个方法就是在要删除的文件的前边加上./。另一种解决的方法是在文件名前边加上"
-- ". rm ./-badname 。 rm -- -badname
rmdir
: 删除目录. 但是只有这个目录中没有文件的时候 -- 当然会包含"不可见的"点文件 -- 这个命令才会成功.
mkdir
: 生成目录, 创建一个空目录. 比如, mkdir -p
project/programs/December将会创建指定的目录,即使project目录和programs目录都不存在. -p选项将会自动产生必要的父目录,
这样也就同时创建了多个目录.
chmod
: 修改一个现存文件的属性。 chmod +x filename , chmod 644
filename
ln
: 创建文件链接, 前提是这个文件是存在的. "链接"就是一个文件的引用, 也就是这个文件的另一个名字. ln命令允许对同一个文件引用多个链接,
并且是避免混淆的一个很好的方法。 ln对于文件来说只不过是创建了一个引用, 一个指针而已, 因为创建出来的连接文件只有几个字节.
绝大多数使用ln命令时, 使用的是-s选项,
可以称为符号链接, 或"软"链接. 使用-s标志的一个优点是它可以穿越文件系统来链接目录. 关于使用这个命令的语法还是有点小技巧的. 比如: ln
-s oldfile newfile将对之前存在的oldfile产生一个新的连接, newfile.如果之前newfile已经存在的话,
将会产生一个错误信息.
不论是那种类型的链接, 都提供了一种双向引用的手段 --
也就是说, 不管你用文件的哪个名字对文件内容进行修改, 你修改的效果都即会影响到原始名字的文件, 也会影响到链接名字的文件. 当你工作在更高层次的时候,
才会发生软硬链接的不同. 硬链接的优点是, 原始文件与链接文件之间是相互独立的 -- 如果你删除或者重命名旧文件, 那么这种操作将不会影响硬链接的文件,
硬链接的文件讲还是原来文件的内容. 然而如果你使用软链接的话, 当你把旧文件删除或重命名后, 软链接将再也找不到原来文件的内容了.
而软链接的优点是它可以跨越文件系统(因为它只不过是文件名的一个引用, 而并不是真正的数据). 与硬链接的另一个不同是,
一个符号链接可以指向一个目录.
man, info
: 这两个命令用来查看系统命令或安装工具的手册和信息. 当两者都可用时, info页一般会比man页包含更多的细节描述.
复杂命令
find
-exec COMMAND
\; 在每一个find匹配到的文件执行COMMAND命令.
命令序列以;结束(";"是转义符以保证shll传递到find命令中的字符不会被解释为其他的特殊字符).如果COMMAND中包含{},
那么find命令将会用所有匹配文件的路径名来替换"{}".
find命令的-exec选项不应该与shell中的内建命令exec相混淆.
find ~/ -name ‘core*‘ -exec
rm {} \; # 从用户的 home 目录中删除所有的 core dump文件.
find /home/bozo/projects
-mtime 1 # 列出最后一天被修改的 # mtime = 目标文件最后修改的时间 # ctime
= 修改后的最后状态(通过‘chmod‘或其他方法) # atime = 最后访问时间
find "$DIR" -type f -atime +5
-exec rm {} \; 删除至少5天内没被访问过的 "/home/bozo/junk_files"
中的所有文件.
expr
: 通用求值表达式: 通过给定的操作(参数必须以空格分开)连接参数, 并对参数求值. 可以使算术操作, 比较操作,
字符串操作或者是逻辑操作.
expr 5 \* 3 #返回15,
在算术表达式expr中使用乘法操作时, 乘法符号必须被转义.
y=`expr $y + 1` 增加变量的值,
与let y=y+1和y=$(($y+1))的效果相同. 这是使用算术表达式的一个例子.
z=`expr substr $string
$position $length` 在位置$position上提取$length长度的子串.
:操作可以替换match命令. 比如, b=`expr
$a : [0-9]*`与b=`expr match $a [0-9]*`完全等价.
时间/日期
命令
date
: 直接调用date命令就会把日期和时间输出到 stdout上.
这个命令有趣的地方在于它的格式化和分析选项上. 需要在调用格式的前边加上一个‘+‘号.
date +%j
# %j用来给出今天是本年度的第几天.
%s将产生从"UNIX
元年"到现在为止的秒数。suffix=$(date +%s) , filename=$prefix.$suffix #
这是一种非常好的产生"唯一"临时文件的办法,甚至比使用$$都强.
touch
: 这是一个用来更新文件被访问或修改的时间的工具, 这个时间可以是当前系统的时间,也可以是指定的时间, 这个命令也用来产生一个新文件. 命令touch
zzz将产生一个zzz为名字的0字节长度文件, 当然前提是zzz文件不存在. 为了存储时间信息, 就需要一个时间戳为空的文件,
比如当你想跟踪一个工程的修改时间的时候, 这就非常有用了.
at : at命令是一个作业控制命令,
用来在指定时间点上执行指定的命令集合. 它有点像cron命令, 然而,
at命令主要还是用来执行那种一次性执行的命令集合. 你可以使用-f选项或者使用(<)重定向操作符, 来让at命令从一个文件中读取命令集合.
这个文件其实就一个可执行的的脚本, 虽然它是一个不可交互的脚本。 at 2:30 am Friday <
at-jobs.list
cal
: 从stdout中输出一个格式比较整齐的日历. 既可以指定当前年度, 也可以指定过去或将来的某个年度.
sleep
:这个命令与一个等待循环的效果一样. 你可以指定需要暂停的秒数, 这段时间将什么都不干。 sleep 3 # 暂停3秒。sleep默认是以秒为单位,
但是你也可以指定分钟, 小时, 或者天数为单位. sleep 3 h # 暂停3小时!
如果你想每隔一段时间来运行一个命令的话, 那么watch命令将比sleep命令好得多.
文本处理命令
sort
: 文件排序, 通常用在管道中当过滤器来使用. 这个命令可以依据指定的关键字或指定的字符位置, 对文件行进行排序. 使用-m选项,
它将会合并预排序的输入文件. 想了解这个命令的全部参数请参考这个命令的info页.
tsort
: 拓扑排序, 读取以空格分隔的有序对, 并且依靠输入模式进行排序.
uniq
:这个过滤器将会删除一个已排序文件中的重复行. 这个命令经常出现在sort命令的管道后边.
cat list-1 list-2 list-3 |
sort | uniq > final.list #
将3个文件连接起来, 将它们排序, 删除其中重复的行,最后将结果重定向到一个文件中.
-c用来统计每行出现的次数,
并把次数作为前缀放到输出行的前面.
sort INPUTFILE | uniq -c |
sort -nr 命令先对INPUTFILE文件进行排序, 然后统计每行出现的次数(sort命令的-nr选项会产生一个数字的反转排序).
这种命令模板一般都用来分析log文件或者用来分析字典列表, 或者用在那些需要检查文本词汇结构的地方.
sed -e ‘s/\.//g‘ -e ‘s/\,//g‘
-e ‘s/ /\
/g‘ "$1" |
tr ‘A-Z‘ ‘a-z‘ | sort | uniq -c | sort -nr #
过滤掉句号和逗号, 并且把单词间的空格转化为换行, 然后转化为小写, 最后统计单词出现的频率并按频率排序.
expand,
unexpand : expand命令将会把每个tab转化为一个空格.
这个命令经常用在管道中.unexpand命令将会把每个空格转化为一个tab. 效果与expand命令相反.
cut : 一个从文件中提取特定域的工具.
这个命令与awk中使用的print $N命令很相似, 但是更受限. 在脚本中使用cut命令会比使用awk命令来得容易一些.
最重要的选项就是-d(字段定界符)和-f(域分隔符)选项.
cut -d ‘ ‘ -f1,2
/etc/mtab
paste : 将多个文件,
以每个文件一列的形式合并到一个文件中, 合并后文件中的每一列就是原来的一个文件.与cut结合使用, 经常用于创建系统log文件.
join : 这个命令与paste命令属于同类命令.
但是它能够完成某些特殊的目地. 这个强力工具能够以一种特殊的形式来合并两个文件,
这种特殊的形式本质上就是一个关联数据库的简单版本.join命令只能够操作两个文件. 它可以将那些具有特定标记域(通常是一个数字标签)的行合并起来,
并且将结果输出到stdout. 被加入的文件应该事先根据标记域进行排序以便于能够正确的匹配.
head : 把文件的头部内容打印到stdout上(默认为10行,
可以自己修改). 这个命令有一些比较有趣的选项.
tail : 将一个文件结尾部分的内容输出到stdout中(默认为10行).
通常用来跟踪一个系统logfile的修改情况,如果使用-f选项的话, 这个命令将会继续显示添加到文件中的行.
为了列出一个文本文件中的指定行的内容,
可以将head命令的输出通过管道传递到tail -1中. 比如head -8 database.txt | tail
-1将会列出database.txt文件第8行的内容.
var=$(head -$m $filename |
tail -$n) # filename = 文件名 # m = 从文件开头到块结尾的行数 # n =
想保存到变量中的指定行数(从块结尾开始截断)
grep : 使用正则表达式的一个多用途文本搜索工具.
这个命令本来是ed行编辑器中的一个命令/过滤器: g/re/p -- global - regular expression -
print.
grep pattern
[file...] 在文件中搜索所有pattern出现的位置, pattern既可以是要搜索的字符串, 也可以是一个正则表达式.
grep ‘[rst]ystem.$‘
osinfo.txt #Linux operating system. #如果没有指定文件参数,
grep通常用在管道中对stdout进行过滤.
-i 选项在搜索时忽略大小写. -w
选项用来匹配整个单词. -l 选项仅列出符合匹配的文件, 而不列出匹配行. -r (递归) 选项不仅在当前工作目录下搜索匹配, 而且搜索子目录. -n
选项列出所有匹配行, 并显示行号. -v (或者--invert-match)选项将会显示所有不匹配的行. -c (--count)
选项将只会显示匹配到的行数的总数,而不会列出具体的匹配.
grep -n Linux osinfo.txt #6:
Linux operating system.
如果存在一个成功的匹配,
那么grep命令将会返回0作为退出状态码, 这样就可以将grep命令的结果放在脚本的条件测试中来使用, 尤其和-q(禁止输出)选项组合时特别有用. grep
-q "$word" "$filename" # "-q"选项将使得什么都不输出到stdout上.
egrep -
扩展的grep - 这个命令与grep -E等价. 这个命令用起来有些不同, 由于使用正则表达式的扩展集合, 将会使得搜索更具灵活性.
它也允许逻辑|(或)操作. egrep ‘matches|Matches‘ file.txt
fgrep - 快速的grep - 这个命令与grep
-F等价. 这是一种按照字符串字面意思进行的搜索(即不允许使用正则表达式), 这样有时候会使搜索变得容易一些.
look :look命令与grep命令很相似,
但是这个命令只能做"字典查询", 也就是它所搜索的文件必须是已经排过序的单词列表. 默认情况下, 如果没有指定搜索哪个文件,
look命令就默认搜索/usr/dict/words(译者:感觉好像应该是/usr/share/dict/words),
当然也可以指定其他目录下的文件进行搜索.
sed, awk
:这个两个命令都是独立的脚本语言, 尤其适合分析文本文件和命令输出. 既可以单独使用, 也可以结合管道和在shell脚本中使用.
sed : 非交互式的"流编辑器", 在批处理模式下,
允许使用多个ex命令. 你会发现它在shell脚本中非常有用.
awk : 可编程的文件提取器和文件格式化工具,
在结构化的文本文件中, 处理或提取特定域(特定列)具有非常好的表现. 它的语法与C语言很类似.
wc : wc可以统计文件或I/O流中的"单词数量":
wc -w 统计单词数量. wc -l 统计行数量. wc
-c 统计字节数量.wc -m 统计字符数量.wc -L 给出文件中最长行的长度.
ls *.txt | wc
-l #因为列出的文件名都是以换行符区分的, 所以使用-l来统计.
tr
: 字符转换过滤器. 必须使用引用或中括号, 这样做才是合理的. 引用可以阻止shell重新解释出现在tr命令序列中的特殊字符.
中括号应该被引用起来防止被shell扩展.
无论tr "A-Z" "*"
<filename还是tr A-Z \* <filename都可以将filename中的大写字符修改为星号(写到stdout).
但是在某些系统上可能就不能正常工作了, 而tr A-Z ‘[**]‘在任何系统上都可以正常工作.
-d选项删除指定范围的字符. echo
"abcdef" | tr -d b-d # aef . tr -d 0-9 <filename #
删除"filename"中所有的数字.
--squeeze-repeats
(或-s)选项用来在重复字符序列中除去除第一个字符以外的所有字符. 这个选项在删除多余空白的时候非常有用. echo "XXXXX" | tr
--squeeze-repeats ‘X‘ # X
-c"complement"选项将会反转匹配的字符集.
通过这个选项, tr将只会对那些不匹配的字符起作用. echo "acfdeb123" | tr -c b-d +
# +c+d+b++++
tr a-z A-Z <"$1" , tr
‘[:lower:]‘ ‘[:upper:]‘ <"$1" 全部转换为大写.
tr ‘a-zA-Z‘ ‘n-za-mN-ZA-M‘ #
"a"变为"n", "b"变为"o", 等等.
fold : 将输入按照指定宽度进行折行. 这里有一个非常有用的选项-s,
这个选项可以使用空格进行断行(译者:事实上只有外文才需要使用空格断行, 中文是不需要的)
fmt : 一个简单的文件格式器, 通常用在管道中, 将一个比较长的文本行输出进行"折行". fmt
-w $WIDTH
col : 这个命令用来滤除标准输入的反向换行符号. 这个工具还可以将空白用等价的tab来替换.
col工具最主要的应用还是从特定的文本处理工具中过滤输出, 比如groff和tbl.
column : 列格式化工具. 通过在合适的位置插入tab,
这个过滤工具会将列类型的文本转化为"易于打印"的表格式进行输出.
ls -l | sed 1d) | column -t # 管道中的"sed 1d"删除输出的第一行,
"column"中的-t选项用来转化为易于打印的表形式.
colrm : 列删除过滤器. 这个工具将会从文件中删除指定的列(列中的字符串)并且写到文件中,
如果指定的列不存在, 那么就回到stdout. colrm 2 4 <filename将会删除filename文件中每行的第2到第4列之间的所有字符.
如果这个文件包含tab和不可打印字符, 那将会引起不可预期的行为. 在这种情况下,
应该通过管道的手段使用expand和unexpand来预处理colrm.
nl : 计算行号过滤器. nl filename将会把filename文件的所有内容都输出到stdout上,
但是会在每个非空行的前面加上连续的行号. 如果没有filename参数, 那么就操作stdin.nl命令的输出与cat -n非常相似, 然而,
默认情况下nl不会列出空行.