tshark 和 powershell 重定向如何创建字节码文本文件?

How can tshark and powershell redirection create a bytecode textfile?

好吧,这实际上是一个我已经能够解决的问题,但我仍然不明白为什么这个问题首先存在。

我一直在网络流量上使用 tshark,目的是创建一个包含可用于机器学习的关键信息的 txt 或 csv 文件。乍一看,该文件看起来非常好,完全符合我的想象。但是,在 python 中,我注意到一些奇怪的初始字符,并且在应用拆分运算符时,我突然开始处理字节码。

我的 powershell 脚本最初看起来像这样:

$src = "G:\...\train_data\"
$dst = $src+"tsharked\"
Write-Output $dst

Get-ChildItem $src -Filter *.pcap | 
Foreach-Object {
    $content = Get-Content $_.FullName
    $filename=$_.BaseName
    tshark -r $_.FullName -T fields -E separator="," -E quote=n -e ip.src -e ip.dst -e tcp.len -e frame.time_relative -e frame.time_delta > $dst$filename.txt
}

现在我尝试在我的 jupyter notebook 中阅读这个文件

directory = "G://.../train_data/tsharked/"
file = open(directory+"example.txt", "r")
for line in file.readlines():
    print(line)
    words = line.split(",")
    print(words)
    break

结果是这样的

ÿþ134.169.109.51,134.169.109.25,543,0.000000000,0.000000000

['ÿþ1\x003\x004\x00.\x001\x006\x009\x00.\x001\x000\x009\x00.\x005\x001\x00', '\x001\x003\x004\x00.\x001\x006\x009\x00.\x001\x000\x009\x00.\x002\x005\x00', '\x005\x004\x003\x00', '\x000\x00.\x000\x000\x000\x000\x000\x000\x000\x000\x000\x00', '\x000\x00.\x000\x000\x000\x000\x000\x000\x000\x000\x000\x00\n']

当我在编辑器中打开文本文件时,没有出现特殊字符ÿþ。这是我第一次见到他们。他们在这里甚至意味着什么? 无论如何,我只能通过删除 powershell 脚本中的输出重定向来解决这个问题。

$src = "G:\...\train_data\"
$dst = $src+"tsharked\"
Write-Output $dst

Get-ChildItem $src -Filter *.pcap | 
Foreach-Object {
    $content = Get-Content $_.FullName
    $filename=$_.BaseName
    $out = tshark -r $_.FullName -T fields -E separator="," -E quote=n -e ip.src -e ip.dst -e tcp.len -e frame.time_relative -e frame.time_delta
    Set-Content -Path $dst$filename.txt -Value $out
}

这就是我问自己的问题,即 powershell 中的输出重定向如何能够成功地写入某种字节输出?在我的理解中,这只是控制台输出的重定向,因此得名。这怎么可能不是字符串?

  • 从 PowerShell 7.2 开始,外部程序的输出在进一步处理之前总是被解码为文本,这意味着原始(字节)输出既不能通过|传递,也不能用>捕获。有关详细信息,请参阅

  • PowerShell 的 > 重定向运算符实际上是 Out-Fileits[=60= 的别名] 因此适用默认字符编码。

Windows PowerShell中,Out-File默认为“Unicode”编码,即UTF-16LE:

  • 此编码使用 BOM(字节顺序标记),其字节如果单独解释为 ANSI(Windows-1252)字节,则呈现为 ÿþ),并且它将大多数字符表示为两个字节序列,[1],对于Windows-1252字符中的大多数字符set (它本身是 ASCII 的超集)意味着每个序列中的 second 字节是一个 NUL0x0 字节) - 这就是你看到了。

幸运的是,在 PowerShell (Core) 7+ 中,所有文件处理 cmdlet 现在 一致地 默认为(无 BOM)UTF -8.

要使用不同的编码,要么显式调用 Out-File 并使用它的 -Encoding 参数,要么 - 正如您所做的那样,在处理数据时为了性能通常更可取已经是 text - 使用 Set-Content.


[1] 每个字符至少需要两个字节;对于所谓的 BMP (Basic Multilingual Plane) 之外的字符,需要 双字节序列。