shell 如何更改程序以使其显示输出

ffx8fchx  于 2023-01-31  发布在  Shell
关注(0)|答案(4)|浏览(126)

我试图打印出2022年世界上最幸福的国家,通过接收来自https://en.wikipedia.org/wiki/World_Happiness_Report?action=raw)的数据。然后编辑显示前5个国家。以下是我的代码:

#!/bin/bash
content=$(curl -s "https://en.wikipedia.org/wiki/World_Happiness_Report?action=raw")
lines=$(echo "$content" | grep '^\|' | sed -n '/2022/{n;p;}')
top_5=$(echo "$lines" | awk '{print $3}' | sort | head -n 5)
echo "$top_5"

然而,当我在Ubuntu中运行这段代码时,什么也没显示,它只是一片空白,就像这样:

....(My computer server).....:~$ bash happy_countriesnew.sh
#(I'm expecting there to be a list here)
....(My computer server).....:~$

我期待这样的结果,而不是我的终端显示的空白:

Finland
Norway
Denmark
Iceland
Switzerland
Netherlands
Canada
New Zealand
Sweden
Australia

我做错了什么,我应该改变什么?

gpfsuwkq

gpfsuwkq1#

echo | grep | sed | awk有点像反模式。通常,您希望将此类管道重构为仅调用awk。在您的示例中,尝试提取2022年数据的代码看起来有缺陷。数据已经排序,因此您可以删除排序并使用以下命令获取所需数据:

sed -n '/^=== 2022 report/,/^=/{ s/}}//; /^|[12345]|/s/.*|//p; }'

所述第一部分(/^=== 2022 report/,/^=/)告诉sed只处理两个给定模式匹配的行,这就是您感兴趣的数据。剩下的就是清理和提取国家名称,只打印第二个字段正好是1、2、3、4或5中的一个的行。注意,这不是非常灵活,而且很难修改它来打印前7名或前12名,所以你可能想要这样的东西:

sed -n '/^=== 2022 report/,/^=/{ s/}}//; /^|[[:digit:]]/s/.*|//p; }' | head -n 5

请注意,可以认为sed | head也是一个反模式,但是跟踪sed中的输出行是很乏味的,并且到head的管道没有尝试编写这样的代码那么令人震惊。

rt4zxlrg

rt4zxlrg2#

我猜你看到了这个错误(但你忽略了它)

grep: empty (sub)expression

这问题是与你的grep表达式,删除ecape

lines=$(echo "$content" | grep '^|' | sed -n '/2022/{n;p;}')

并检查错误。

mcvgt66p

mcvgt66p3#

使用awk

awk -F"{{|}}|[|]" '/^=== 2022 rep/ {f=1} /^=== 2021 rep/ {f=0} {if(f==1 && /flag/) {print $6}}' <<<"$content" | head -n 5
Finland
Denmark
Iceland
Switzerland
Netherlands

-F"{{|}}|[|]" #将字段分隔符设置为"{{"或"}}"或"|"
/^=== 2022 rep/ {f=1} #如果行以"=== 2022 rep"开头,则设置标志
/^=== 2021 rep/ {f=0} #如果行以"=== 2021 rep"开头,则取消设置标志
{if(f==1 && /flag/) {print $6}}' #如果设置了f且行包含"标志"文本,则打印第6个字段
注:假设通过content=$(curl -s "https://en.wikipedia.org/wiki/World_Happiness_Report?action=raw")填充"$content"变量

  • 或者-
    您可以使用bash命令替换,并完全避免中间变量content
awk -F"{{|}}|[|]"  '/^=== 2022 rep/ {f=1} /^=== 2021 rep/ {f=0} {if(f==1 && /flag/) {print $6}}' < <(curl -s "https://en.wikipedia.org/wiki/World_Happiness_Report?action=raw") | head -n 5

输出:

Finland
Denmark
Iceland
Switzerland
Netherlands
pbgvytdp

pbgvytdp4#

curl …………… | 

gawk 'NF *= 2<NF' FS='^[|][1-5][|][|][{][{]flag[|]|[}][}]$' OFS=
Finland
Denmark
Iceland
Switzerland
Netherlands

如果你想进一步缩小:

mawk 'NF *= 2<NF' FS='^[|][1-5][|].+[|]|[}]+$' OFS=

这种方法很容易将列表扩展到,比如说,Top17:

nawk 'NF *= 2<NF' FS='^[|]([1-9]|1[0-7])[|].+[|]|[}]+$' OFS=

相关问题