【发布时间】:2012-02-03 17:10:46
【问题描述】:
我正在尝试在 Unix 中复制 cat 命令的功能。
我想避免将两个文件显式读入变量,将变量连接在一起,然后写出连接变量的解决方案。
【问题讨论】:
-
关于通过 copy 操作合并文件的密切相关问题:stackoverflow.com/q/71209707/45375
标签: powershell merge text-files powershell-2.0
我正在尝试在 Unix 中复制 cat 命令的功能。
我想避免将两个文件显式读入变量,将变量连接在一起,然后写出连接变量的解决方案。
【问题讨论】:
标签: powershell merge text-files powershell-2.0
只需使用Get-Content 和Set-Content cmdlet:
Get-Content inputFile1.txt, inputFile2.txt | Set-Content joinedFile.txt
您也可以使用这种样式连接两个以上的文件。
如果源文件名称相似,可以使用通配符:
Get-Content inputFile*.txt | Set-Content joinedFile.txt
注意 1: PowerShell 5 和更早的版本允许使用别名 cat 和 sc 分别为 Get-Content 和 Set-Content 更简洁地完成此操作。但是,这些别名是有问题的,因为 cat 是 *nix 系统中的系统命令,而 sc 是 Windows 系统中的系统命令 - 因此不建议使用它们,实际上 sc 甚至不再定义为PowerShell 核心 (v7)。 PowerShell 团队recommends against using aliases in general。
注意 2:小心使用通配符 - 如果您尝试输出到 inputFiles.txt(或与模式匹配的类似内容),PowerShell 将进入无限循环! (我刚刚测试过。)
注意 3:输出到带有> 的文件不会保留字符编码!这就是推荐使用Set-Content 的原因。
【讨论】:
Set-Content 使用国家代码页(例如,英语为 Windows-1252)。如果源文件包含其他编码(例如 Windows-1251 或 UTF8),您必须设置正确的编码sc file.txt -Encoding UTF8(从 v6.2 开始支持俄语的 1251 等数字)
Add-Content 的问题是,如果您运行该命令两次,聚合文件的长度会增加一倍。一个很好的替代品是Out-File。示例here
Get-Content my.bin -Raw | Set-Content my.bin -NoNewline 不会改变 my.bin,除了时间戳。 -Raw 保留任何 CR/LF 字节,而 -NoNewline 阻止 PowerShell 添加自己的 CR/LF 字节。
不要使用>;它弄乱了字符编码。使用:
Get-Content files.* | Set-Content newfile.file
【讨论】:
cat 是 Get-Content 的别名。
> 时,在我的连接文件的开头得到ÿþ FF FE。
> 是Out-File 的有效别名,在 Windows PowerShell 中默认为“Unicode”(UTF-16LE),而Set-Content 默认为系统的旧版 ANSI 代码页。虽然后一种编码问题较少,但请注意 both cmdlet 有可能改变输入文件的编码,因为它们的默认编码与输入文件的编码无关(这是 PowerShell不提供)。请注意,幸运的是 PowerShell (Core) 7+ 现在默认为(BOM-less)UTF-8,在所有 cmdlet 中保持一致。
您可以使用Add-Content cmdlet。也许它比其他解决方案快一点,因为我不检索第一个文件的内容。
gc .\file2.txt| Add-Content -Path .\file1.txt
【讨论】:
gc 指的是什么?
gc 是 Get-Content 的别名
gc (Get-Content) 是否默认逐行检索文件内容。使用Set-Content,而不是Add-Content,因为后者将保留输出文件中任何预先存在的内容。请注意,可能会在输出文件中使用不同的字符编码(无论您使用什么 cmdlet),如已接受答案的 cmets 中所述。
要在命令提示符下连接文件
type file1.txt file2.txt file3.txt > files.txt
PowerShell 将type 命令转换为Get-Content,这意味着在PowerShell 中使用type 命令时会出错,因为Get-Content 命令需要用逗号分隔文件。 PowerShell 中的相同命令是
Get-Content file1.txt,file2.txt,file3.txt | Set-Content files.txt
【讨论】:
如果您需要按特定参数(例如日期时间)对文件进行排序:
gci *.log | sort LastWriteTime | % {$(Get-Content $_)} | Set-Content result.log
【讨论】:
我用过:
Get-Content c:\FileToAppend_*.log | Out-File -FilePath C:\DestinationFile.log
-Encoding ASCII -Append
这很好。我添加了 ASCII 编码以删除 Notepad++ 在没有显式编码的情况下显示的 nul 字符。
【讨论】:
保持编码和行尾:
Get-Content files.* -Raw | Set-Content newfile.file -NoNewline
注意:AFAIR,旧 Powershell 不支持其参数 (
【讨论】:
-Encoding unicode 添加到您建议的命令末尾(除了您的两个参数之外)允许Excel 正确打开CSV 文件的组合。请参阅docs.microsoft.com/en-us/powershell/module/… 了解更多信息。
你可以这样做:
get-content input_file1 > output_file
get-content input_file2 >> output_file
其中> 是“out-file”的别名,>> 是“out-file -append”的别名。
【讨论】:
由于大多数其他回复经常出现格式错误(由于管道),因此最安全的做法如下:
add-content $YourMasterFile -value (get-content $SomeAdditionalFile)
我知道您想避免将 $SomeAdditionalFile 的内容读入变量,但为了保存例如您的换行符格式,我认为没有正确的方法可以做到这一点。
一种解决方法是逐行遍历您的 $SomeAdditionalFile 并将其通过管道传输到您的 $YourMasterFile。然而,这过于耗费资源。
【讨论】:
我认为“powershell方式”可能是:
set-content destination.log -value (get-content c:\FileToAppend_*.log )
【讨论】: