这是作业!
我正在编写一个shell脚本,它本质上会创建一个书籍数据库,该文件包含所有输入的书籍,如
J.K。罗琳:哈利波特:我不知道:200年代
作者(S)1:TITLE1:Publisher1:YEAR1
作者(S)2:标题2:Publisher2:YEAR2
。
。
。
作者(S)(N):标题(N):出版商(N):年(n)的
现在我使用grep搜索在命令行中输入的特定搜索模式,让我们说“哈利波特”,它将输出所有带有字符串“哈利波特”的条目
我有
的工作grep $2 "bookprint.txt"
然而它打印的内容与输入到文件中的内容相同......作者1:title1:Publisher1:year1
我想格式化字符串,这样它就会打印4行,每行分成2列,所以输出看起来像
作者(S):.. J.K。罗琳
标题:...........哈利波特
出版商:......我不知道
年份:2000 ..........的
(假装句号是空格我无法正确格式化以显示我想要的内容)
这里的任何提示都将非常感激
答案 0 :(得分:1)
仅使用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找到第一次出现的“old”并将其替换为“new”。因此,例如:
$ echo "this is so old" | sed 's/old/new/'
this is so new
我们使用的第一个替代品是:
s/^/Author(s)! /
对于sed,插入符号(^
)是一个特殊字符,它与行的开头匹配。因此,这种替代使得“作者!”被放置在该行的开头。
第二个替代命令是
s/:/\nTitle! /
这会导致第一次出现冒号(“:”)被“\ nTitle!”替换,其中\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用冒号替换每个感叹号。这给出了你想要的结果。
答案 1 :(得分:0)
我建议您尝试使用gawk
来完成此类任务(尽管可以使用纯bash
完成)。使用gawk
,您可以这样做:
gawk -v SEARCH="${2}" -F ":" '$0 ~ SEARCH {for (i=1;i<=NF;i++) { print $i }}'
gawk
(-v SEARCH="${2}
)-F ":"
)$0
)没有gawk
(和sed
):
IFS=":" read -a array <<< $(grep $2 bookprint.txt)
for element in "${array[@]}"
do
echo "$element"
done
注意 仅在只有一条匹配记录时才有效。它可以用更多的记录,但我们不是来解决你的功课。您应该自己研究并尝试解决方案。并阅读精细手册。并学习。
答案 2 :(得分:0)
除了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包含“Harry Potter”,grep会给你一个错误,比如“没有这样的文件:Potter”(假设你没有名为Potter的文件)