![将 awk -v 与 Shell 变量一起使用效果很好并打印到终端,但是当重定向到文件时,只有第一条记录打印到该文件](https://linux22.com/image/225223/%E5%B0%86%20awk%20-v%20%E4%B8%8E%20Shell%20%E5%8F%98%E9%87%8F%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E6%95%88%E6%9E%9C%E5%BE%88%E5%A5%BD%E5%B9%B6%E6%89%93%E5%8D%B0%E5%88%B0%E7%BB%88%E7%AB%AF%EF%BC%8C%E4%BD%86%E6%98%AF%E5%BD%93%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0%E6%96%87%E4%BB%B6%E6%97%B6%EF%BC%8C%E5%8F%AA%E6%9C%89%E7%AC%AC%E4%B8%80%E6%9D%A1%E8%AE%B0%E5%BD%95%E6%89%93%E5%8D%B0%E5%88%B0%E8%AF%A5%E6%96%87%E4%BB%B6.png)
我正在读取具有匹配模式的文件,然后获取匹配模式后的前五行。这些模式的数字顺序不正确,因此我在模式中使用数字变量来按数字顺序循环遍历每组记录。它按数字顺序将所有九个记录打印到终端,但如果我重定向到文件,它不会将任何内容打印到终端,而只将第一条记录打印到文件。如果我只为一个匹配模式插入一个数值,而不是递增变量,它会打印到终端和仅匹配一个模式 1 - 9 的文件。这是导致问题的行。
awk -v data="$devnum" '$0~data{print $0
for (i=1; i<=5; i++) {getline; print}}' $data > $devicedata
如果我 rm ,> $devicedata
它会打印到终端,如果我替换"$devnum"
为匹配的模式,/device 3/
它会将第三条记录和接下来的 4 行打印到终端并输出到文件。如果有任何不正确的格式,我深表歉意。感谢您的任何帮助!对于更新,我相信我应该将问题视为“不明确的重定向”。我确实尝试通过管道传输到 tee 命令并附加 >>,但我又回到了使用 2>&1 进行重定向,这消除了我已经忘记的“不明确的重定向”。 $data=devices.txt 和 $devicedata=devicedata.txt。
答案1
无论您在重定向方面遇到什么问题,它都与 -v 无关。运行你的脚本http://shellcheck.net并解决它告诉您的问题。
您当前的症状几乎可以肯定是因为 devicedata 中存储的值包含空格,因此未加引号的> $devicedata
扩展为多个重定向目标,因此引用> "$devicedata"
将解决不明确的重定向,但这可能不是您唯一的问题。
以下是如何从 bash 获取不明确的重定向错误的示例:
$ devicedata='foo'
$ echo 'hi' > $devicedata
$ devicedata='foo bar'
$ echo 'hi' > $devicedata
-bash: $devicedata: ambiguous redirect
以下是消除该错误消息的方法:
$ echo 'hi' > "$devicedata"
$
现在您需要弄清楚的剩下的事情是为什么您的devicedata
变量包含空格以及这是否是您想要/期望的。
shell 中的引号不是您在需要时添加的内容,它们是您默认使用的内容,并在需要时删除。您应该始终在 shell 中使用双引号变量,除非您有非常具体的理由不这样做并完全理解删除这些引号的含义,请参阅https://mywiki.wooledge.org/Quotes。
如果您在运行 shellcheck 等后仍然遇到问题,请确保发布一个最小、完整的 shell 脚本,我们可以帮助您调试,因为问题与您的 awk 脚本无关。话虽如此 - 你想要做的事情不是你应该使用 getline 的情况,请参阅https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105,如果您不应该这样称呼它,请参阅 awk.freeshell.org/AllAboutGetline。
FWIW我会把你的脚本写成(未经测试):
awk -v devnum="$devnum" '$0~devnum{c=5} c&&c--' "$data" > "$devicedata"
data
出于某种目的用作 awk 变量的名称,然后又data
出于完全不同的目的用作 shell 变量的名称,这很令人困惑,因此我重命名了其中一个。