bash$ cat testfile
This line occurs only once.
This line occurs twice.
This line occurs twice.
This line occurs three times.
This line occurs three times.
This line occurs three times.
bash$ uniq -c testfile
1 This line occurs only once.
2 This line occurs twice.
3 This line occurs three times.
bash$ sort testfile | uniq -c | sort -nr
3 This line occurs three times.
2 This line occurs twice.
1 This line occurs only once.
bash$ cat testfile
This line occurs only once.
This line occurs twice.
This line occurs twice.
This line occurs three times.
This line occurs three times.
This line occurs three times.
bash$ ./wf.sh testfile
6 this
6 occurs
6 line
3 times
3 three
2 twice
1 only
1 once
expand, unexpand
unexpand过滤器将空格转换为制表符。起着和expand相反的作用。
cut
使用cut获得已挂载文件系统的列表:
cut -d ' ' -f1,2 /etc/mtab
使用cut列出操作系统和内核版本:
uname -a | cut -d" " -f1,3,11,1
使用cut从电子邮件文件夹中提取消息头(message header):
bash$ grep '^Subject:' read-messages | cut -c10-80
Re: Linux suitable for mission-critical apps?
MAKE MILLIONS WORKING AT HOME!!!
Spam complaint
Re: Spam complaint
使用cut解析文件:
# 列出所有在/etc/passwd中的用户。
FILENAME=/etc/passwd
for user in $(cut -d: -f1 $FILENAME)
do
echo $user
done
# 感谢Oleg Philon提出的建议。
bash$ grep Linux osinfo.txt misc.txt
osinfo.txt:This is a file containing information about Linux.
osinfo.txt:The GPL governs the distribution of the Linux operating system.
misc.txt:The Linux operating system is steadily gaining in popularity.
要强制grep在仅搜索一个目标文件时显示文件名,只需将/dev/null作为第二个文件即可。
bash$ grep Linux osinfo.txt /dev/null
osinfo.txt:This is a file containing information about Linux.
osinfo.txt:The GPL governs the distribution of the Linux operating system.
SUCCESS=0 # 如果grep查找成功
word=Linux
filename=data.file
grep -q "$word" "$filename" # "-q"选项会
# 导致什么都不在stdout中输出
if [ $? -eq $SUCCESS ]
# if grep -q "$word" "$filename" 可以替换 5 - 7 行。
then
echo "$word found in $filename"
else
echo "$word not found in $filename"
fi
样例 16-17. 在脚本中模仿grep命令
#!/bin/bash
# grp.sh: 实现grep命令的基本功能。
E_BADARGS=85
if [ -z "$1" ] # 检查脚本的参数。
then
echo "Usage: `basename $0` pattern"
exit $E_BADARGS
fi
echo
for file in * # 遍历$PWD中的全部文件
do
output=$(sed -n /"$1"/p $file) # 命令替换。
if [ ! -z "$output" ] # 如果"$output"没有引用会发生什么?
then
echo -n "$file: "
echo "$output"
fi # sed -ne "/$1/s|^|${file}: |p" 与上等效。
echo
done
echo
exit 0
# 练习:
# ---------
# 1) 如果在任何给定文件中有多个匹配项,则将换行符添加到输出中。
# 2) 添加特性。
# Filename: tstfile
This is a sample file.
This is an ordinary text file.
This file does not contain any unusual text.
This file is not unusual.
Here is some text.
现在,让我们在这个文件中搜索同时包含"file"和"text"的行. . .
bash$ grep file tstfile
# Filename: tstfile
This is a sample file.
This is an ordinary text file.
This file does not contain any unusual text.
This file is not unusual.
bash$ grep file tstfile | grep text
This is an ordinary text file.
This file does not contain any unusual text.
现在,让我们来玩一下grep吧~~
样例 16-18. 纵横字谜解算器
#!/bin/bash
# cw-solver.sh
# 这脚本实际上就是围绕一条命令的包装而已(46行).
# 填字游戏和anagramming文字游戏求解器。
# 你知道你要找的单词中的 *一些* 字母,
# 所以你需要一个列表,
# 列出在给定的位置上所有有效的单词和已知的字母。
# 例如: w...i....n
# 1???5????10
# w在位置1, 3个未知字母, i在位置5, 4个未知字母, n在末尾。
# (请参阅脚本末尾的注释。)
E_NOPATT=71
DICT=/usr/share/dict/word.lst
# ^^^^^^^^ 在这里寻找单词列表。
# ASCII单词列表,一行一个字母。
# 如果你碰巧需要这么一个单词列表,
# 请下载作者的 “yawl” 单词列表包。
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
# 或者
# http://bash.deta.in/yawl-0.3.2.tar.gz
if [ -z "$1" ] # 如果没有单词模式指定为命令行参数 . . .
then
echo #+ . . . 那么 . . .
echo "Usage:" #+ 打印使用信息。
echo
echo ""$0" \"pattern,\""
echo "where \"pattern\" is in the form"
echo "xxx..x.x..."
echo
echo "The x's represent known letters,"
echo "and the periods are unknown letters (blanks)."
echo "Letters and periods can be in any position."
echo "For example, try: sh cw-solver.sh w...i....n"
echo
exit $E_NOPATT
fi
echo
# ===============================================
# 这是所有工作完成的地方。
grep ^"$1"$ "$DICT" # 没错,就一行代码!
# | |
# ^ 匹配输入字符串的开始位置。
# $ 匹配输入字符串的结束位置。
# 摘自 _Stupid Grep Tricks_, vol. 1,
# 《ABS指南》(本书)的作者会再去里面找找看还有什么好玩的
# . . . 可能就这几天吧 . . .
# ===============================================
echo
exit $? # 脚本到此停止执行。
# 如果生成的单词太多,
# 请将输出重定向到文件。
$ sh cw-solver.sh w...i....n
wellington
workingman
workingmen
bash $ egrep 'matches|Matches' file.txt
Line 1 matches.
Line 3 Matches.
Line 4 contains matches, but also Matches
样例 16-19. 在Webster 1913字典中查找定义
#!/bin/bash
# dict-lookup.sh
# 此脚本在1913 Webster的词典中查找定义.
# 该公共领域词典可从多个站点下载,
# 比如Gutenberg项目(http://www.gutenberg.org/etext/247)。
#
# 在使用该脚本之前,
# 请将其从DOS格式转换成UNIX格式(行末尾只有LF)
# 将文件存储在普通的、未压缩的ASCII文本中。
# 将下面的DEFAULT_DICTFILE变量设置为路径/文件名。
E_BADARGS=85
MAXCONTEXTLINES=50 # 要显示的最大行数。
DEFAULT_DICTFILE="/usr/share/dict/webster1913-dict.txt"
# 默认的字典文件路径。
# 有必要的话请重新设置。
# 注意:
# ----
# 该特定版本的1913 Webster字典每个单词以大写字母开头
# (单词剩下的部分为小写字母)。
# 只有条目的 *第一行* 以这种方式开始,
# 这就是下面的搜索算法起作用的原因。
if [[ -z $(echo "$1" | sed -n '/^[A-Z]/p') ]]
# 必须至少要指定要查找的单词,并且
# 它必须以大写字母开头。
then
echo "Usage: `basename $0` Word-to-define [dictionary-file]"
echo
echo "Note: Word to look up must start with capital letter,"
echo "with the rest of the word in lowercase."
echo "--------------------------------------------"
echo "Examples: Abandon, Dictionary, Marking, etc."
exit $E_BADARGS
fi
if [ -z "$2" ] # 可以指定不同的字典
# 来作为此脚本的参数。
then
dictfile=$DEFAULT_DICTFILE
else
dictfile="$2"
fi
# ---------------------------------------------------------
Definition=$(fgrep -A $MAXCONTEXTLINES "$1 \\" "$dictfile")
# 展现形式定义为 "Word \..."
#
# 而且,是的,“fgrep” 足够快,甚至可以搜索非常大的文本文件。
# 现在,裁剪定义块。
echo "$Definition" |
sed -n '1,/^[A-Z]/p' |
# 从输出的第一行打印到下一个条目的第一行。
sed '$d' | sed '$d'
# 删除最后两行输出
# (下一个条目的空行和第一行)。
# ---------------------------------------------------------
exit $?
# 练习:
# ---------
# 1) 修改脚本以接受任何类型的字母输入
# (大写、小写、混合格式),并且将其转换为可接受的格式进行处理。
#
# 2) 将脚本转换为GUI应用程序,
# 使用诸如'gdialog'或'zenity'等工具 . . .
# 脚本将不再从命令行中获取参数。
#
# 3) 修改脚本以解析其他可用的公共领域词典之一,
# 例如美国人口普查局地名词典(U.S. Census Bureau Gazetteer)。