用于抓取特定模式后的输出行的脚本

发布于 2024-12-19 09:03:39 字数 643 浏览 0 评论 0原文

我有一个程序,准确地说是“wimaxcu scan”,它以如下格式输出数据:

network A
frequency
signal strength
noise ratio

network B
frequency
signal strength
noise ratio

etc....

该程序输出了大量元素。我只对一个特定网络的一些属性感兴趣,例如网络 J。我想编写一个 bash 脚本,每隔一段时间将 J 的信号强度和噪声比放在指定文本文件的新行上我运行脚本的时间。因此,在多次运行脚本后,我会得到一个如下所示的文件:

Point 1 signal_strength noise_ratio
Point 2 signal_strength noise_ratio
Point 3 signal_strength noise_ratio
etc...

建议我将输出通过管道传输到 grep 中来完成此操作。我相当确定 grep 不是实现此目的的最佳方法,因为我想要抓取的行与其他噪声和信号强度行无法区分。我认为必须识别“网络 J”模式(它是唯一的),然后将抓取找到的模式之后的第二行和第三行。

我的问题是其他人如何建议我实现这样的脚本。我对 bash 不太有经验,所以最简单的方法将受到赞赏,而不是复杂但有效的方法。

I have a program, "wimaxcu scan" to be precise, that outputs data in a format like the following:

network A
frequency
signal strength
noise ratio

network B
frequency
signal strength
noise ratio

etc....

There are a huge number of elements that get output by the program. I am only interested in a few of the properties of one particular network, say for example network J. I would like to write a bash script that will place the signal strength and noise ratio of J on a new line in a specified text file every time that I run the script. So after running the script many times I would have a file that looks like:

Point 1 signal_strength noise_ratio
Point 2 signal_strength noise_ratio
Point 3 signal_strength noise_ratio
etc...

I was advised to pipe the output into grep to accomplish this. I'm fairly certain that grep is not the best method to accomplish this because the lines I want to grab are indistinguishable from other noise and signal strengths lines. I'm thinking that the "network J" pattern would have to be recognized (it is unique), and then the lines that come 2nd and 3rd after the found pattern would be grabbed.

My question is how others would recommend that I implement such a script. I'm not very experienced with bash, so the simplest method would be appreciated, rather than a complex but efficient method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沉溺在你眼里的海 2024-12-26 09:03:40

这可能对你有用:

# cat file1 # same format for file2, file3, ...
network A
frequency
signalA strength
noise1 ratio

network B
frequency
signalB strength
noise1 ratio
# sed -n '/network/{s/network \(.\)/cat <<\\EOF >>\1/p;n;n;N;y/ /_/;s/\n/ /;s/$/\nEOF/p}' file1 | sh
# sed -n '/network/{s/network \(.\)/cat <<\\EOF >>\1/p;n;n;N;y/ /_/;s/\n/ /;s/$/\nEOF/p}' file2 | sh
# sed -n '/network/{s/network \(.\)/cat <<\\EOF >>\1/p;n;n;N;y/ /_/;s/\n/ /;s/$/\nEOF/p}' file3 | sh
# sed -i = A 
# sed -i 'N;s/^/Point /;s/\n/ /' A
# sed -i = B 
# sed -i 'N;s/^/Point /;s/\n/ /' B
# cat A     
Point 1 signalA_strength noise1_ratio
Point 2 signalA_strength noise2_ratio
Point 3 signalA_strength noise3_ratio
# cat B
Point 1 signalB_strength noise1_ratio
Point 2 signalB_strength noise2_ratio
Point 3 signalB_strength noise3_ratio

This might work for you:

# cat file1 # same format for file2, file3, ...
network A
frequency
signalA strength
noise1 ratio

network B
frequency
signalB strength
noise1 ratio
# sed -n '/network/{s/network \(.\)/cat <<\\EOF >>\1/p;n;n;N;y/ /_/;s/\n/ /;s/$/\nEOF/p}' file1 | sh
# sed -n '/network/{s/network \(.\)/cat <<\\EOF >>\1/p;n;n;N;y/ /_/;s/\n/ /;s/$/\nEOF/p}' file2 | sh
# sed -n '/network/{s/network \(.\)/cat <<\\EOF >>\1/p;n;n;N;y/ /_/;s/\n/ /;s/$/\nEOF/p}' file3 | sh
# sed -i = A 
# sed -i 'N;s/^/Point /;s/\n/ /' A
# sed -i = B 
# sed -i 'N;s/^/Point /;s/\n/ /' B
# cat A     
Point 1 signalA_strength noise1_ratio
Point 2 signalA_strength noise2_ratio
Point 3 signalA_strength noise3_ratio
# cat B
Point 1 signalB_strength noise1_ratio
Point 2 signalB_strength noise2_ratio
Point 3 signalB_strength noise3_ratio
海的爱人是光 2024-12-26 09:03:39

用awk!

如果您的数据位于名为“data”的文件中,则可以在命令行上执行此操作:

$ awk -v RS='\n\n' -v FS='\n' '{ print $1,$3,$4 }' data

将“记录分隔符”设置为两个换行符,将“字段分隔符”设置为单个换行符,然后打印字段每个数据集中有一个、三个和四个。

如果您不熟悉的话,awk 对记录进行操作,并且可以用它们做各种事情。所以这只是说“记录看起来像这样,并以这种方式打印”。具体来说,“一条记录具有由换行符分隔的字段,并且每个记录由两个连续的换行符分隔。为每个记录打印出这些记录的第一个、第三个和第四个字段。”

编辑: 正如 Jo So(他完全阅读并理解了您所要求的内容)所指出的,您可以在花括号内部添加一个 if 语句来指定特定的网络。或者,如果它是唯一的,您可以在末尾添加一个管道来 grep 。但他的解决方案更正确,因为它只会与第一个字段匹配!

$ awk -v RS='\n\n' -v FS='\n' '{ if ($1 == "Network J") print $1,$3,$4 }' data

With awk!

If your data is in a file called "data," you can do this on the command line:

$ awk -v RS='\n\n' -v FS='\n' '{ print $1,$3,$4 }' data

What that will do is set your "record separator" to two newlines, the "field separator" to a single newline, and then print fields one, three, and four from each data set.

Awk, if you're not familiar, operates on records, and can do various things with them. So this simply says "a record looks like this, and print it this way." Specifically, "A record has fields that are separated by newlines, and each record is separated by two consecutive newlines. Print the first, third, and fourth fields of these records out for each record."

Edit: As Jo So (who fully read and comprehended what you were asking for) points out, you can add an if statement to the inside of the curly braces to specify a specific network. Or, if it were unique, you could just throw in a pipe to grep at the end. But his solution is more correct, since it will only match against that first field!

$ awk -v RS='\n\n' -v FS='\n' '{ if ($1 == "Network J") print $1,$3,$4 }' data
枯叶蝶 2024-12-26 09:03:39

为了完成 Dan Fego 的非常好的答案(抱歉,似乎我还不允许发表评论),请考虑这一点:

awk -v RS='\n\n' -v FS='\n' '{if ($1 == "network J") print $3}' data

这实际上是一段非常健壮的代码。

To complete Dan Fego's very good answer (sorry, it seems I'm not yet allowed to place comments), consider this:

awk -v RS='\n\n' -v FS='\n' '{if ($1 == "network J") print $3}' data

This is actually a very robust piece of code.

ˇ宁静的妩媚 2024-12-26 09:03:39

实际上 Grep 是正确的选择。

您所要做的就是使用 grep 的 -A (之后)和 -B (之前)选项。您可以使用类似的内容:

grep "network J" -A 3   original_output

这将输出网络 J 之后的 3 行,包括网络 J 行。但是您不想要“网络 J”一词,因此

grep "network J" -A 3   original_output | grep -v "network J"

您必须将它们放在一行中,这可以通过回显轻松完成输出如下:

echo $(grep "network J" -A  original_output | grep -v "network J")

现在您将在文件中看到 Network J 的所有实例。您可以将它们附加到输出

A 部分

   echo $(grep "network J" -A original_output | grep -v "network J") >> net_j_report.txt

在开头添加 Point 1 ... 等,稍后可以通过以下方式完成:

B 部分

   grep -v '^[[:space:]]*

这里 grep -v 删除任何意外的空行, cat -n 添加行号,最后一个 sed 语句放置单词点在开头。

所以将 A 部分和 B 部分结合起来,瞧。

net_j_report.txt | cat -n | sed -e 's/^/Point /'

这里 grep -v 删除任何意外的空行, cat -n 添加行号,最后一个 sed 语句放置单词点在开头。

所以将 A 部分和 B 部分结合起来,瞧。

Actually Grep is the right option.

What you have to do is use the -A (after) and -B (before) options of grep. You can use something like:

grep "network J" -A 3   original_output

this will output the 3 lines after network J including the line network J. But you don't want the words "network J" so

grep "network J" -A 3   original_output | grep -v "network J"

you then have to put them in one line which is easily done by echoing the output as in:.

echo $(grep "network J" -A  original_output | grep -v "network J")

Now you will end up with all instances of Network J in the file. you can append them to an output

Part A

   echo $(grep "network J" -A original_output | grep -v "network J") >> net_j_report.txt

adding Point 1 ... etc to the beginning can be done later by:

Part B

   grep -v '^[[:space:]]*

here grep -v removes any accidental empty lines, cat -n adds line numbers and last sed statement puts the word Point in the beginning.

so combine part A and B and voila.

net_j_report.txt | cat -n | sed -e 's/^/Point /'

here grep -v removes any accidental empty lines, cat -n adds line numbers and last sed statement puts the word Point in the beginning.

so combine part A and B and voila.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文