我正在通过像这样的简单批处理脚本合并两个ASCII文件
COPY a.txt+b.txt c.txt /y /a
问题是,C中的最后一个字符被设置为1A
,即SUB
的HEX表示法。 c.txt被送入另一个不喜欢最后1A
的可执行文件。
生成c.txt之后,如果我在Notepad ++中打开它并删除最后一个字符,那么该文件就可以正常工作。
我怎样才能合并a.txt
和b.txt
而1A
没有c.txt
附加到{{1}}的末尾?
答案 0 :(得分:29)
放置/a
和/b
开关至关重要。它们的执行方式不同,具体取决于它们是放在源文件名还是目标文件名之后。
当与目标文件名一起使用时,/a
会导致添加文件结束标记(ASCII 26)。你实际上是在指定这个!
/a
指定文件是ASCII并且它被复制到但不包括第一个ASCII 26文件结束标记。该字符及其后的任何内容都会被忽略。
/b
会导致整个文件被复制,包括任何文件结束标记及其后的任何内容。
/a
导致ASCII 26被添加为最后一个字符。
/b
不会将ASCII 26添加为最后一个字符。
...虽然我没有测试过,但可能会使用
COPY a.txt+b.txt /a c.txt /b /y
答案 1 :(得分:1)
您可以将开关/a
(ASCII-Text)更改为/b
(二进制)
另请参阅copy /?
所以生成的命令是
COPY a.txt+b.txt c.txt /y /b
答案 2 :(得分:1)
从copy
更改为type
type a.txt>c.txt
type b.txt>>c.txt
答案 3 :(得分:1)
我认为@Andrew的样本是错的,但实际上它比我的更正确。
问题是,[/A | /B]
说明符可以双向工作。
这有点让人困惑。 copy /?
显示[/ A | / B]在第一个源文件之前,也在每个其他源之后以及在目标之后
COPY ... [/ A | / B]来源[/ A | / B] [+来源[/ A | / B] ...] [目的地[/ A | / B]]
说明符实际上适用于之前的文件,但也适用于其后的所有文件,包括目标。 但只有直到在命令行上找到相反的说明符,在这种情况下,后面的说明符适用于它之后的所有文件,但也适用于之前的文件。
将复制命令默认值组合为ASCII
样品。
copy aa + bb + cc dd
ASCII ASCII ASCII ASCII
指定要复制为二进制文件的所有文件,接下来的三个样本具有相同的效果:
copy /b aa + bb + cc dd
bin bin bin bin
copy aa /b + bb + cc dd
bin bin bin bin
copy aa + /b bb + cc dd
bin bin bin bin
还有一些测试:
copy aa + bb /a + cc dd
ASCII ASCII ASCII ASCII
copy aa + bb /b + cc dd
ASCII BIN BIN BIN
copy /b aa + bb + cc dd /a
bin bin bin ascii
copy aa /a + bb + cc dd /b
ASCII ASCII ASCII bin
copy aa + bb + cc dd /b
ASCII ASCII ASCII bin
copy aa + bb + cc /a dd /b
ASCII ASCII ASCII bin
但是如果重新使用source作为目标,则目标类型将覆盖同一文件上的源类型:
copy aa + bb + cc aa /b
BIN ASCII ASCII BIN
copy aa + bb + cc /b aa
BIN ASCII BIN BIN
这意味着我的原始示例实际上是将所有文件复制为二进制文件,并且覆盖了开头的/ A.现在它也在做同样的事情,但它看起来更好。
@Andrew示例正在做他所承诺的事情,只是/ A在那里没用。如果要将一个文件添加到另一个文件,则不需要第三个文件。再次使用第一个作为目的地。不能成为第二个,或者在阅读之前你会覆盖它。
这是我用来连接文件列表中所有文本文件的脚本。
@echo off
set concatenated=final.js
pushd %~dp0
set error=
copy nul "%concatenated%"
if errorlevel 1 set error=true
for /f %%a in (filelist.txt) do (
echo. && echo.
echo. *** %%a
copy /B /V "%concatenated%" + "%%a" "%concatenated%"
if errorlevel 1 set error=true
)
popd
echo.
if defined error (echo. !!!!!!!!! THERE WERE ERRORS !!!!!!!!!!
) else echo. *** ALL DONE ***
echo.
pause
exit /b
答案 4 :(得分:1)
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/copy
如果/ a在命令行上位于文件列表的前面或后面,则它将 适用于列出的所有文件,直到复制遇到/ b。在这种情况下,/ b 适用于/ b之前的文件。
/ a的效果取决于它在命令行字符串中的位置:- 如果/ a跟随源,则copy命令将文件视为ASCII 文件并复制第一个文件结尾字符之前的数据 (CTRL + Z)。 -如果/ a跟随目标,则copy命令将添加一个 文件结尾字符(CTRL + Z)作为文件的最后一个字符。
如果/ b指示命令解释器读取字节数 由目录中的文件大小指定。 / b是默认值 复制,除非复制合并文件。
如果/ b在命令行上在文件列表之前或之后,它将 适用于所有列出的文件,直到副本遇到/ a。在这种情况下,/ a 适用于/ a之前的文件。
这是一条冗长的说法: 合并文件时的默认值为/ a。 这意味着/ a选项在您的代码段中是多余的,并且无论/ a放在何处都将应用。
解决方案是使用/ b,这指示它在读取时忽略#1A [DOS文件结尾]字符,并且在写入时不输出。
与/ a不同,如果源文件包含#1A字符,则/ b的位置很重要。如果/ b在命令末尾,则文件将被截断到#1A(但不包括#1A)。
以下任何一项都可以纠正此行为:
COPY a.txt+b.txt c.txt /y /b
COPY a.txt+b.txt /b c.txt /y
COPY /b a.txt+b.txt c.txt /y
但是在不使用DOS文件结尾表示文件结尾的情况下,只有以下内容才有效:
COPY a.txt /b + b.txt c.txt /y
COPY /b a.txt + b.txt c.txt /y
注意:为了进一步混淆,在源文件之后添加/ b会将/ b应用于之后的每个源文件,直到出现/ a。
在正常操作中,此行为看起来似乎很奇怪。由于DOS文件系统始终记录文件大小,因此文件结尾字符应该是多余的。
https://en.wikipedia.org/wiki/End-of-file
这样做有两个原因:
与CP / M的向后兼容性。 CP / M文件系统仅以128字节“记录”的倍数记录文件的长度,因此 按照惯例,Control-Z字符用于标记 有意义的数据(如果它在记录中间结束)。 MS-DOS 文件系统始终记录文件的确切字节长度,因此这 在MS-DOS上根本不需要。
它允许程序使用相同的代码从终端和文本文件中读取输入。
其结果是,它允许人们从设备(例如COM端口)获取输入或输出到设备,同时仍然能够区分不同的文件。
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/copy
您可以用设备名称代替一个或多个出现的源或目的地。