Shell 格式化从Grep提交的每个字符串
这是作业强> 我正在写一个shell脚本,它将创建一个图书数据库,这个文件保存了所有输入的图书 J.K.罗琳:哈利·波特:我不知道:200秒 作者1:标题1:出版商1:年份1Shell 格式化从Grep提交的每个字符串,shell,unix,file-io,Shell,Unix,File Io,这是作业 我正在写一个shell脚本,它将创建一个图书数据库,这个文件保存了所有输入的图书 J.K.罗琳:哈利·波特:我不知道:200秒 作者1:标题1:出版商1:年份1 作者2:标题2:出版商2:年份2 . . . 作者(n):标题(n):出版商(n):年份(n) 现在,我使用grep搜索一个特定的搜索模式,该模式输入到命令行中,比如说“Harry Potter”,它将输出所有带有字符串“Harry Potter in it”的条目 我和他一起工作 grep $2 "bookprint.txt
作者2:标题2:出版商2:年份2
.
.
.
作者(n):标题(n):出版商(n):年份(n) 现在,我使用grep搜索一个特定的搜索模式,该模式输入到命令行中,比如说“Harry Potter”,它将输出所有带有字符串“Harry Potter in it”的条目 我和他一起工作
grep $2 "bookprint.txt"
但是,它打印出的所有内容都与输入到文件中的内容相同。。。。作者1:title1:Publisher1:year1
但是,我想格式化字符串,这样它将打印4行单独的行,每行分成2列,因此输出如下
作者:…J.K。罗琳标题:……哈利波特
出版商:……我不知道
年份:2000年
(假设句点是空白,我无法正确格式化它们以显示我想要的内容)
非常感谢这里的任何提示对于此类任务,我建议尝试
gawk
(尽管可以使用纯bash
)。使用gawk
你可以像这样做:
gawk -v SEARCH="${2}" -F ":" '$0 ~ SEARCH {for (i=1;i<=NF;i++) { print $i }}'
注意只有在只有一条匹配记录的情况下才有效。有更多的记录是可行的,但我们不是来解决你的家庭作业的。你应该自己研究并尝试解决方案。阅读精美的手册。并学习。仅使用sed和grep:
grep "$2" "bookprint.txt" | sed 's/^/Author(s)! /; s/:/\nTitle! /; s/:/\nPublisher! /; s/:/\nYear! /; s/!/:/g'
在示例中进行测试,以显示sed命令的样例输出:
$ echo "J.K. Rowling:Harry Potter:I dont know:2000's" | sed 's/^/Author(s)! /; s/:/\nTitle! /; s/:/\nPublisher! /; s/:/\nYear! /; s/!/:/g'
Author(s): J.K. Rowling
Title: Harry Potter
Publisher: I dont know
Year: 2000's
工作原理:sed进行了五次替换。一般来说,每个替换都像“s/old/new/”一样工作。这指示sed查找第一个出现的“旧”并替换为“新”。因此,例如:
$ echo "this is so old" | sed 's/old/new/'
this is so new
我们使用的第一个替代品是:
s/^/Author(s)! /
对于sed,插入符号(^
)是一个特殊字符,它与行首匹配。因此,此替换将导致“Author(s)!”放在行的开头
第二个替代命令是
s/:/\nTitle! /
这会导致第一次出现的冒号(“:”)被替换为“\n冒号!”,其中\n
被视为换行符
如果我们只使用这两个命令,结果将是:
$ echo "J.K. Rowling:Harry Potter:I dont know:2000's" | sed 's/^/Author(s)! /; s/:/\nTitle! /'
Author(s)! J.K. Rowling
Title! Harry Potter:I dont know:2000's
所以,我们仍然需要输入出版商和年份
查看上面的输出,您将看到,在完成上面的两个替换之后,第一个冒号正好出现在发布者名称之前。因此,第三个替代命令是:
s/:/\nPublisher! /
此命令将第一次出现的冒号(“:”)替换为“\nPublisher!”。年份行的创建方式与替换相同:
s/:/\nYear! /
只有这四个替代品,我们才能:
$ echo "J.K. Rowling:Harry Potter:I dont know:2000's" | sed 's/^/Author(s)! /; s/:/\nTitle! /; s/:/\nPublisher! /; s/:/\nYear! /'
Author(s)! J.K. Rowling
Title! Harry Potter
Publisher! I dont know
Year! 2000's
这看起来不错,只是我们需要冒号的地方有感叹号。因此,我们需要的最后一个替代品是:
s/!/:/g
注意末尾的“g”。这告诉sed在全球范围内进行这种替代。因此,这个替换告诉sed用冒号替换每个感叹号。这将提供您想要的结果。除了shell之外,您不需要任何东西来解析和格式化:
grep "$2" bookprint.txt | while IFS=: read -r author title publisher year; do
echo "Author(S): $author"
echo "Title: $title"
echo "Publisher: $publisher"
echo "Year: $year"
done
引用grep命令中的
“$2”
非常重要:如果$2包含“哈利·波特”,grep会给你一个错误,比如“没有这样的文件:波特”(假设你没有名为波特的文件)我想我不允许使用该命令,我想我只允许使用find,sed和grepIt可以通过sed完成。我会看看我是否能想出一个答案。哇,谢谢!我对所有的斜杠和东西都不熟悉,你能推荐一个好的指南/网站吗?在那里我可以阅读say“s/^/Author(s)!/;”的确切功能以及它是如何工作的,这样我就可以在将来创建类似的东西了?@coookiemoster我已经添加了一个解释作为开始。有关基础知识的更多信息,请参阅bash简介和sed简介。
grep "$2" bookprint.txt | while IFS=: read -r author title publisher year; do
echo "Author(S): $author"
echo "Title: $title"
echo "Publisher: $publisher"
echo "Year: $year"
done