【问题标题】:Iterating over files, save the last line of the file and the filename on a text file via STDOUT and pipe遍历文件,通过 STDOUT 和管道将文件的最后一行和文件名保存在文本文件中
【发布时间】:2025-12-23 12:15:12
【问题描述】:

昨天我问了如何将控制台输出保存在文件中的问题(请参阅redirect only last line of STDOUT to a file)。现在我遍历文件,编译它们。这是我的命令:

for REPORT in Test_Basic_*.scala; do
    scalac -Xplugin:divbyzero.jar $REPORT | awk 'END{print $REPORT} END{print}' >> output.txt
done

我想保存编译的最后输出和文件名。在上面的例子中,只有 $REPORT 会被保存,但我想引用迭代变量的名称。

例如我有文件 Test_Condition.scala 并运行上面的命令:

for REPORT in Test_Basic_*.scala; do
    scalac -Xplugin:divbyzero.jar $REPORT | awk 'END{print $REPORT} END{print}' >> output.txt;
done

然后scalac -Xplugin:divbyzero.jar $REPORT 产生以下输出:

You have overwritten the standard meaning
Literal:()
rhs type: Int(1)
Constant Type: Constant(1)
We have a literal constant
List(localhost.Low)
Constant Type: Constant(1)
Literal:1
rhs type: Int(2)
Constant Type: Constant(2)
We have a literal constant
List(localhost.High)
Constant Type: Constant(2)
Literal:2
rhs type: Boolean(true)
Constant Type: Constant(true)
We have a literal constant
List(localhost.High)
Constant Type: Constant(true)
Literal:true
LEVEL: H
LEVEL: H
okay
LEVEL: H
okay
false
symboltable: Map(a -> 219 | Int | object TestIfConditionWithElseAccept2 | normalTermination | L, c -> 221 | Boolean | object TestIfConditionWithElseAccept2 | normalTermination | H, b -> 220 | Int | object TestIfConditionWithElseAccept2 | normalTermination | H)
pc: Set(L, H)

现在我想在 output.txt 中保存Test_Condition.scala(文件名)和pc: Set(L, H)(编译输出的最后一行)。使用上面的命令,我只保存$REPORT pc: Set(L, H)

如果这个解释很复杂,请告诉我。感谢您的大力支持。

马蒂亚斯

【问题讨论】:

    标签: bash shell awk


    【解决方案1】:

    您只会得到文字“$REPORT”,因为您的 awk 脚本用单引号括起来,这会阻止 shell 替换 REPORT 变量。

    试试这个:

    scalac ... "$REPORT" | awk -v filename="$REPORT" 'END {print filename; print}' >> output
    

    -v 选项设置一个名为 filename 的 awk 变量来保存 shell 的 REPORT 变量的值。

    此外,始终引用 shell 变量是一个很好的经验法则(除非您特别希望省略它们的副作用)。

    【讨论】:

    • 另一种选择是使用ENVIRON awk 变量。 ... | awk 'END { print ENVIRON["SHELL"]; print }'
    • @jamessan,是的,但您必须先导出变量。
    【解决方案2】:

    如果我正确解释了您的问题,您只需要一种方法来对一堆文件执行命令,然后存储文件名和命令输出的最后一行。这应该有效:

    : > output # 清除输出文件 对于 Test_Basic_*.scala 中的文件;做 printf "$file:" >> 输出 斯卡拉克... | awk 'END { print }' >> 输出 完毕

    【讨论】:

    • 正是我想要的,非常感谢威廉,你救了我这一天,我学会了“printf”命令。
    • 您可以将重定向移到末尾,您不必先清除文件:for ... done > output