【问题标题】:I am having trouble removing new lines from text in a shell script (using sed and grep)我无法从 shell 脚本中的文本中删除新行(使用 sed 和 grep)
【发布时间】:2023-12-28 01:05:01
【问题描述】:

我在 macOS 上使用 zsh

我有一个 shell 脚本,它生成一个带有 speedtest 结果的文本文件,布局如下:

 Download:    63.57 Mbps (data used: 69.3 MB)                               

 Upload:    16.11 Mbps (data used: 23.0 MB) 

                          

我可以操纵布局并产生这个:

↓ 63.57 Mbps | 
↑ 16.11 Mbps 

注意第一行文本之前的换行符和管道之后的换行符。在终端中只打印出最后一行:↑ 16.11 Mbps

转换输入的脚本是这样的:

DOWNLOAD=$(cat ~/Terminal_Projects/temp_speedtest_result.txt | grep Download | sed 's/   Download:    /↓ /g' | sed 's/ (data used: //g' | sed -E 's/[0-9]{1,4}\.[0-9] MB)//g' | sed 's/\n\r\t//')
UPLOAD=$(cat ~/Terminal_Projects/temp_speedtest_result.txt | grep Upload | sed 's/     Upload:    /↑ /g' | sed 's/ (data used: //g' | sed -E 's/[0-9]{1,4}\.[0-9] MB)//g' | tr '\n' ' ')
RESULT=$DOWNLOAD" | "$UPLOAD
echo $RESULT

我使用了多个 sed 实例,因为我无法让它在一个实例中工作。你可能知道如何让它工作。

我想要做的是在一行上输出 DOWNLOAD 和 UPLOAD 变量。我有另一个非常相似的脚本,它通过完全相同的变量操作来实现。

我尝试过的:

使用 RESULT="$DOWNLOAD | $UPLOAD"

使用 RESULT="${DOWNLOAD} | ${UPLOAD}"

使用tr '\n' ' '代替sed命令删除\n

如果不支持这些符号,我尝试删除向上和向下箭头 - 相同的行为。

我尝试在 RESULT 变量上使用 sed 来尝试删除新行。我还尝试将 RESULT 变量的内容写入一个新的临时 txt 文件,然后检索文件的内容并使用 grep 逐一提取结果,希望不会复制新行。没有为我工作。 看起来有我无法删除的换行符,但我可能是错的。

我是命令行和 shell 脚本的新手。试图将我非常有限的知识应用于新场景。任何帮助将不胜感激。

【问题讨论】:

  • 如果输入文件中有多个DownloadUpload 行,您希望它是什么样子?还是保证永远不会发生?

标签: shell unix terminal command-line-interface zsh


【解决方案1】:

怎么样

RESULT="$(grep -Ew '(Down|Up)load' <~/Terminal_Projects/temp_speedtest_result.txt | tr '\n' ' ')"

?这更有效(只需要一个 greptr 进程)并且还通过使用RESULT=$DOWNLOAD" | "$UPLOAD 中的管道修复了您在解决方案中遇到的错误(应该已显示错误消息)。

【讨论】:

  • 对不起,这仍然会给我一个跨多行的结果,但是我认为我的初始字符串提取效率低下,因为我提取了两次相似的字符串。
  • 不可能,因为tr 删除了换行符。您可以使用示例RESULT=$((echo a1 ; echo b1) |tr '\n' ' ') 进行尝试,该示例将RESULT 设置为a1 b1(不带换行符)。
  • 是的,您的脚本按预期工作。我同意 tr 应该可以工作,我什至认为它应该可以在我的原始脚本上工作,这就是为什么在我最终承认并在这里写下我的问题之前,我花了几个小时挠头。我认为一定有其他事情发生;也许它实际上与删除新行无关 - 但我是一个我不知道的新手。
  • @Dan :很难说,因为在您的问题中,您针对该问题提出了各种尝试,存在各种错误,并且没有明确的正确解决方案可供查看。如果我的建议符合您的要求,您会考虑接受它作为正确答案吗?
  • Costi 的回答(上图)有效,我已经将其标记为正确。正如您在技术上所说,您的答案也删除了换行符 - 只是由于某种原因不在我的确切情况下。我刚刚也尝试将您的标记为正确,但 SO 似乎每个问题只允许一个正确的解决方案。所以我想把 Costi's 作为正确答案,因为它解决了我提出的问题。
【解决方案2】:

tr 似乎可以完成这项工作,而echo -n "$UPLOAD" 显示在一行上,所以我认为您走在正确的轨道上,只需要修复 DOWNLOAD 部分。

我建议您使用以下内容稍微简化脚本:

INPUT_FILE="~/Terminal_Projects/temp_speedtest_result.txt"

DOWNLOAD="$(grep Download $INPUT_FILE | awk '{print "↓" $2 " " $3}' | tr '\n' ' ')"
UPLOAD="$(grep Upload $INPUT_FILE | awk '{print "↓" $2 " " $3}' | tr '\n' ' ')"

echo "$DOWNLOAD | $UPLOAD"

【讨论】:

  • 谢谢。这行得通。我现在可以在我的菜单栏中看到向下和上传速度!看来我需要更熟悉awk。我已经实现了您建议的代码,并在上传字符串中进行了一些小的编辑↑,我附加了sed 's/Upload://g' 并下载了等效代码,因为我想通过将“上传:”替换为“↑”来缩短字符串。感谢您提供如此大的帮助。
  • 您可以通过将模式放入 awk 调用中来消除 grep: awk '/Download/ {print....}' $INPUT_FILE |转...
最近更新 更多