输入文件我的.txt
文件包含这些内容:
Tom Thatcher's Fortune, by Horatio Alger, Jr. 56896
Paradise Lost, by John Milton 20
第一个字符串是书名,第二个字符串是作者,最后一个字符串是书号。当有人搜索书号时(如果书号匹配),我想打印整行。我是 bash 脚本新手。
答案1
就像是
grep BOOKNUMBER textfile.txt
应该解决这个问题。
如果您想避免搜索第 96 本书也列出了《汤姆·撒切尔的财富》,您可以使用
grep '[[:space:]]BOOKNUMBER[[:space:]]*$' textfile.txt
反而。
作为脚本(另存为searchbook
)
#!/bin/bash
BOOKFILE=/path/to/bookfile.txt
BOOK=$1
if [[ -z "$BOOK" ]]; then
echo -n "Booknumber? "
read BOOK
fi
grep '[[:space:]]'$BOOK'[[:space:]]*$' $BOOKFILE
然后你可以运行
searchbook BOOKNUMBER
或者
searchbook
在第二种情况下,系统将提示您输入号码。
答案2
您可以grep
为此使用:
grep 56896 file.txt
如果你想编写脚本,它可能是这样的:
#!/bin/bash
inputfile='/path/to/file.txt'
grep "$1" "$inputfile"
然后你会像这样运行:
$ ./script.sh 56896
答案3
为了避免将 book #196
与 book # 一起捕获96
,我建议使用类似但更简洁的用法grep
:
grep ' 96$' file.txt
正则表达式中的符号$
表示“文本示例的结尾”,因此它只会在正确的行上匹配。
这也可以放入脚本中:
#!/bin/bash
grep " ${1}\$" /path/to/file.txt
这也可以通过以下方法更安全地完成awk
:
awk -v book=96 '$NF == book {print}' file.txt
答案4
要打印最后一个单词是什么的行,awk
我想到:
awk '$NF == "123"' # string comparison
awk '$NF == 123' # number comparison, would also match on 0123, 123.0, 1.23e2
awk '$NF == ENVIRON["ENVVAR"]' # number comparison if both $NF and $ENVVAR
# look like numbers, string otherwise
为了awk
那些字默认情况下以空格分隔。取决于实施空白的可能只是空格或制表符,有些可能包括其他 Unicode 空白字符(如果在区域设置中如此分类)。该busybox
awk
实现还包括垂直间隔字符,其中包括回车符。
如果您的文件使用 MS-DOS 行分隔符进行格式化,即 CR LF 字符序列而不是 LF,那么除了 busybox awk 之外,上述方法将不起作用。即使使用 busybox awk,输出行仍然会包含那些在 Unix 上不应该出现的有问题的控制字符。
dos2unix
因此,您应该使用或预处理输入,d2u
将行结尾转换为 Unix 格式。
< file.dos dos2unix | awk '$NF == 123'
您的输入文件看起来像是由空行分隔的记录组成的。如果您想打印书号的完整记录,您可以这样做:
export BOOKNUMBER=123
< file.dos dos2unix | awk -v RS= -F '\n' '
field[split($1, field, " ")] == ENVIRON["BOOKNUMBER"]'
在那里,我们设置了记录分隔符 到空字符串来输入段落模式(记录以空行分隔),以及字段分隔符到换行符(又名 LF),因此每个记录的第一行位于$1
(第一个字段)。我们将第一行与特殊的" "
我们使用默认的单词分裂到field
数组中。然后将该数组的最后一个元素(split()
返回元素的数量,field[split()]
最后一个元素也是)与环境变量的内容进行比较$BOOKNUMBER
。