首先,我才学习 Powershell 大约一周,主要是调整 Linux 脚本以在我的(功能更强大的)Windows 机器上运行。所以,请善用术语。
我正在尝试编写一个脚本,在写入时解析另一个命令写入 stdout 的字符串数据流。写入的数据量很大且很长,最好在写入时对其进行处理,而不是将其写入文本文件然后再进行处理。
输出是带有换行符分隔符的 ASCII 字符串(或者在 Windows 中,也可能是回车符)。以下是我想要执行的实际操作:
foreach ($i in (ffprobe -i "$sourceFile" -show_frames))
{
if ("$i".Substring(0,1) -eq "[" -and "$i".Substring(1,1) -ne "/")
{
echo "$i".Substring(0,1)
echo "$i".Substring(1,1)
echo "$i"
<do other stuff>
}
}
该ffprobe -i "$sourceFile" -show_frames
命令输出如下文本:
[FRAME]
DATA1
DATA1
[/FRAME]
基本上,我想将写入 stdout 的数据视为“while 循环”,直到没有更多内容写入。我一次只需要解析一行数据。总而言之,我预计输出的行数大约在 500 万到 1000 万行之间。
仅供参考,我的机器应该能够处理大量数据。我有双 Xeon E5 v3,12 个内核(24 个超线程)和 128GB RAM。当我处理数据时,大约每 10-15 行输出将被处理并写入文本文件 - 尽管我可能会创建一个缓冲变量来写入处理后的输出,并每隔几千行输出将其刷新到文件中。
提前感谢您的指导。
答案1
以下方法解决了我的问题。我不知道这是否是最有效的方法,但对我来说很有效。如果你有更有效的方法,我欢迎你。
wsl ffprobe -i "$sourceFile" -show_frames 2>1 | ForEach-Object ($_) {
if ("$_".Substring(0,1) -eq "[" -and "$_".Substring(1,1) -ne "/")
{
echo $i
echo "$_".Substring(0,1)
echo "$_".Substring(1,1)
echo "$_"
}
}
*********** 更新 2020-04-12 ***********
事实证明,我不需要使用 WSL - 这只是我发现的第一个解决方案。无论是否使用,上述解决方案都可以按书面形式工作wsl
(此外,您还可以避免将 Windows 文件传递给 WSL 时可能出现的命名问题)。因此,在这种情况下不需要 WSL。最初,当我在 Powershell 中测试方法时,我认为它由于语法错误而失败。具体来说,以下设置失败了:
ffprobe -i "$sourceFile" -show_frames 2>1 | ForEach-Object ($_)
{ # Open Brace in this line instead of previous line
if ("$_".Substring(0,1) -eq "[" -and "$_".Substring(1,1) -ne "/")
{
echo $i
echo "$_".Substring(0,1)
echo "$_".Substring(1,1)
echo "$_"
}
}
{
请注意,的左括号ForEach-Object
不与命令在同一行ForEach-Object
,而是在下一行。由于我不知道的原因,Powershell 脚本会失败。但是,当像上面的解决方案一样设置时,没有wsl
左ForEach-Object
括号{
在同一行,管道输入到循环中就可以正常工作。所以,为了彻底起见,这里是没有的解决方案的样子wsl
:
ffprobe -i "$sourceFile" -show_frames 2>1 | ForEach-Object ($_) {
if ("$_".Substring(0,1) -eq "[" -and "$_".Substring(1,1) -ne "/")
{
echo $i
echo "$_".Substring(0,1)
echo "$_".Substring(1,1)
echo "$_"
}
}