Windows中是否有替代cat命令的工具?

348
我需要用Windows的*.bat脚本将两个二进制文件合并,该如何实现?

20
您的标题问题和描述问题并不完全同步。对于标题问题,type将是最佳答案,而对于描述问题,copy /b将是最佳答案。如果可能的话,您可能需要更改该标题。 - Joseph
2
@Joseph 由于在Windows上二进制和文本文件之间存在区别,因此type只能替换部分cat的功能。 - jfs
交叉复制:https://superuser.com/q/434870/52365 - GSerg
请注意,cat 不仅仅是将文件连接在一起;它还可以将标准输入复制到标准输出(当没有参数调用时)。有关如何在 Windows 上实现此操作,请参见此问题:https://stackoverflow.com/q/52330841 - Simon Kissane
11个回答

503

Windows的type命令与UNIX的cat命令类似。

示例1:

type file1 file2 > file3

等价于:

cat file1 file2 > file3

例子2:

type  *.vcf > all_in_one.vcf  

此命令将把所有的vCard合并为一个。

1
在这种情况下,类型的问题是当在命令行上指定多个文件时,它会添加不必要的文件头。 - Greg Hewgill
2
在命令行上指定多个文件时,输入类型会输出几行空白和文件名,然后再复制文件内容。试试看 :) - Greg Hewgill
4
啊,我没注意到标题会被发送到标准错误输出。知道这点很好。 - Greg Hewgill
1
请注意,箭头类型(如上所示)无法处理大文件(如> 2 GB或4),至少在XP中是如此。但是,您可以使用“复制”命令(请参见其他答案)。 - rogerdpack
3
另一个提示:为了避免显示任何其他输出,请使用以下命令 type file1 file2 > file3 2>NUL - Mike T
显示剩余3条评论

92

你可以像这样使用copy /b

copy /b file1+file2 destfile

5
你可以使用通配符来操作一系列文件,例如"copy /b file* destfile"。通配符将匹配以"file"开头的所有文件,并将它们作为一个序列进行复制。 - Stalinko
1
对我来说很奇怪,为什么这不是被接受的答案,鉴于在被接受的答案的评论中概述了有关“类型”的明显问题...除非这个解决方案有类似的缺点,但不够流行,人们没有注意到它们! - Jony Thrive
谢谢!对我有用。由于某种原因,“type”在输出文件中重复了两次内容。 - kohane15

24
如果您可以控制您工作的机器,我强烈建议安装GnuWin32。只需“下载全部”并让wget程序检索所有软件包即可。然后,您将可以访问cat、grep、find、gzip、tar、less和数百个其他软件。GnuWin32是我在新的Windows系统上安装的第一件事情之一。

我建议使用GetGnuWin32(以简化安装过程)。 - jfs
3
如果可以使用外部工具,我更喜欢用适用于Windows的BusyBox,它是一个单独的 ~600 kB 可执行文件,包含大约30个Unix实用程序。唯一的区别是应该使用"busybox cat"命令,而不是简单的"cat"命令。 - Fr0sT

15

无耻地宣传PowerShell(因为我认为其学习曲线很陡峭,所以在任何机会上教授一些东西都可以帮助)

Get-Content file1,file2

请注意,type 是 Get-Content 的别名,因此如果您喜欢它,可以这样写:

type file1,file2

1
它能工作,但是速度极慢。我在等待 PowerShell 将一些大型视频文件串联起来,每个文件需要半小时的时间时发现了这个问题。我终止了该进程并使用 type file1 file2 > dest 在 cmd 中尝试,每个文件仅需几秒钟就完成了。 - stib
1
请注意,PowerShell 可能会损坏您的二进制文件,例如,\n 可能会被替换为 \r\n - jfs
它以某种原因将我的文件转换为UTF-16。-Encoding UTF8 没有改变任何东西。 - John Dvorak
1
@stib 因为 Get-Content 适用于文本,你需要使用 -AsByteStream 来告诉它不要将其拆分成行。在旧版 PowerShell 中,你需要使用 -Raw-Encoding Byte - phuclv
@JohnDvorak Get-Content默认返回文本行,.NET框架中始终为UTF-16。请参见上面的评论以获取二进制文件。 - phuclv

7
只需使用dos复制命令,将多个源文件和一个目标文件组合在一起。
copy file1+file2 appendedfile

您可能需要使用/B选项来处理二进制文件。

2
在Windows 10的Redstone 1版本中,Windows为NTOS内核添加了一个真正的Linux子系统。我认为最初是为了支持Android应用程序和可能的docker类型场景而设计的。Microsoft与Canonical合作并添加了一个实际的本地bash shell。此外,您可以使用apt软件包管理器获取许多Ubuntu软件包。例如,您可以执行apt-get gcc来安装GCC工具链,就像在Linux上一样。
如果我在大学期间有这样的东西,我想我可以在本地Windows bash shell中完成大部分Unix编程作业。

1

因此,我正在寻找一种类似的解决方案,具有保留行尾字符的功能,但发现没有办法,所以我做了我最擅长的事情,并制作了自己的实用程序。这是一个适用于Windows的本地cat可执行文件 - https://mega.nz/#!6AVgwQhL!qJ1sxx-tLtpBkPIUx__iQDGKAIfmb21GHLFerhNoaWk

Usage: cat file1 file2 file3 file4 -o output.txt
-o | Specifies the next arg is the output, we must use this rather than ">>" to preserve the line endings

我称之为sharp-cat,因为它是用C#构建的,欢迎使用杀毒软件进行扫描,源代码可根据请求提供。

1
如果您只想将文本追加到现有文件的末尾,您可以使用“>>”管道。例如:
echo new text >>existingFile.txt

0
如果您必须使用批处理脚本并已安装Python,则可以使用以下批处理和Python的polyglot答案:
1>2# : ^
'''
@echo off
python "%~nx0" " %~nx1" "%~nx2" "%~nx3"
exit /b
rem ^
'''
import sys
import os

sys.argv = [argv.strip() for argv in sys.argv]
if len(sys.argv) != 4:
    sys.exit(1)

_, file_one, file_two, out_file = sys.argv

for file_name in [file_one, file_two]:
    if not os.path.isfile(file_name):
        print "Can't find: {0}".format(file_name)
        sys.exit(1)

if os.path.isfile(out_file):
    print "Output file exists and will be overwritten"

with open(out_file, "wb") as out:
    with open(file_one, "rb") as f1:
        out.write(f1.read())

    with open(file_two, "rb") as f2:
        out.write(f2.read())

如果保存为 join.bat,则使用方法如下:
join.bat file_one.bin file_two.bin out_file.bin

感谢这个答案的启发。


0

Windows类型的命令存在问题,例如在512字节边界上使用Unicode字符。尝试使用Cygwin的cat命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接