Batch file 批处理脚本从文件中删除BOM(ï;»;¿;)

Batch file 批处理脚本从文件中删除BOM(ï;»;¿;),batch-file,byte-order-mark,Batch File,Byte Order Mark,我创建了一个批处理脚本,将SQL文件从文件夹复制到一个大的SQL脚本中。问题是,当我运行这个SQL脚本时,它会出现错误 “”附近的语法不正确 我将一个SQL脚本复制到Notepad++中,并将编码设置为ANSI。我在发生错误的行上看到这个符号(BOM) 我是否可以在批处理脚本中自动删除它。我不希望每次运行此任务时都手动删除它 下面是我目前拥有的批处理脚本 @echo off set "path2work=C:\StoredProcedures" cd /d "%path2work%" ech

我创建了一个批处理脚本,将SQL文件从文件夹复制到一个大的SQL脚本中。问题是,当我运行这个SQL脚本时,它会出现错误

“”附近的语法不正确

我将一个SQL脚本复制到Notepad++中,并将编码设置为ANSI。我在发生错误的行上看到这个符号(BOM)

我是否可以在批处理脚本中自动删除它。我不希望每次运行此任务时都手动删除它

下面是我目前拥有的批处理脚本

@echo off

set "path2work=C:\StoredProcedures"
cd /d "%path2work%"

echo. > C:\FinalScript\AllScripts.sql

for %%a in (*.sql) do (

    echo. >>"C:\FinalScript\AllScripts.sql"
    echo GO >>"C:\FinalScript\AllScripts.sql"
    type "%%a">>"C:\FinalScript\AllScripts.sql"
    echo. >>"C:\FinalScript\AllScripts.sql"
)

您只需将编码更改为不带BOM的UTF-8并保存文件


请注意,在较旧的Notepad++版本上,菜单项有点不同,您只需将编码更改为UTF-8(不带BOM)并保存文件即可


请注意,菜单项在较旧的记事本++版本上稍有不同,正如MSalters alreadyx在他的评论中所提到的,根据
ï»
是UTF8 BOM的ANSI表示

与批处理相比,PowerShell更适合处理编码的任务:

## Q:\Test\2018\09\11\SO_522772705.ps1
Set-Location 'C:\StoredProcedures'
Get-ChildItem '*.sql' | ForEach-Object {
    "`nGO"
    Get-Content $_.FullName -Encoding UTF8
    ""
} | Set-Content 'C:\FinalScript\AllScripts.sql' -Encoding UTF8
要使用标签
batch file
a批调用基本部件的powershell,请访问主题:

:: Q:\Test\2018\09\11\SO_522772705..cmd
@echo off
set "path2work=C:\StoredProcedures"
cd /d "%path2work%"

powershell -NoProfile -Command "Get-ChildItem '*.sql'|ForEach-Object{\"`nGO\";Get-Content $_.FullName -Enc UTF8;\"\"}|Set-Content 'C:\FinalScript\AllScripts.sql' -Enc UTF8"

正如MSalters alreadyx在他的评论中所提到的,根据
ï»
是UTF8 BOM的ANSI表示

与批处理相比,PowerShell更适合处理编码的任务:

## Q:\Test\2018\09\11\SO_522772705.ps1
Set-Location 'C:\StoredProcedures'
Get-ChildItem '*.sql' | ForEach-Object {
    "`nGO"
    Get-Content $_.FullName -Encoding UTF8
    ""
} | Set-Content 'C:\FinalScript\AllScripts.sql' -Encoding UTF8
要使用标签
batch file
a批调用基本部件的powershell,请访问主题:

:: Q:\Test\2018\09\11\SO_522772705..cmd
@echo off
set "path2work=C:\StoredProcedures"
cd /d "%path2work%"

powershell -NoProfile -Command "Get-ChildItem '*.sql'|ForEach-Object{\"`nGO\";Get-Content $_.FullName -Enc UTF8;\"\"}|Set-Content 'C:\FinalScript\AllScripts.sql' -Enc UTF8"

这是因为
type
命令将保留UTF-8 BOM表,因此,当您组合具有BOM表的多个文件时,最终文件将在文件中间的不同位置包含多个BOM表

如果确定要合并的所有SQL文件都从BOM表开始,则可以使用以下脚本在实际合并它们之前从每个SQL文件中删除BOM表

这是通过管道化
类型的输出来完成的。管道的另一端将在3个
暂停
命令的帮助下使用前3个字节(BOM表)。每次暂停将消耗一个字节。流的其余部分将被发送到
findstr
命令,以将其附加到最终脚本中

由于SQL文件采用UTF-8编码,并且可能包含Unicode范围内的任何字符,因此某些代码页将干扰操作,并可能导致最终SQL脚本损坏

因此,已经考虑到这一点,批处理文件将使用代码页437重新启动,这对于访问任何二进制序列都是安全的

@echo off
setlocal DisableDelayedExpansion


setlocal EnableDelayedExpansion
for /F "tokens=*" %%a in ('chcp') do for %%b in (%%a) do set "CP=%%~nb"
if  !CP! NEQ 437 if !CP! NEQ 65001 chcp 437 >nul && (

    REM for file operations, the script must restatred in a new instance.
    "%COMSPEC%" /c "%~f0"

    REM Restoring previous code page
    chcp !CP! >nul
    exit /b
)
endlocal


set "RemoveUTF8BOM=(pause & pause & pause)>nul"
set "echoNL=echo("
set "FinalScript=C:\FinalScript\AllScripts.sql"

:: If you want the final script to start with UTF-8 BOM (This is optional)
:: Create an empty file in NotePad and save it as UTF8-BOM.txt with UTF-8 encoding.
:: Or Create a file in your HexEditor with this byte sequence: EF BB BF
:: and save it as UTF8-BOM.txt
:: The file must be exactly 3 bytes with the above sequence.
(
    type "UTF8-BOM.txt" 2>nul

    REM This assumes that all sql files start with UTF-8 BOM
    REM If not, then they will loose their first 3 otherwise legitimate characters.
    REM Resulting in a final corrupted script.
    for %%A in (*.sql) do (type "%%~A" & %echoNL%)|(%RemoveUTF8BOM% & findstr "^")

)>"%FinalScript%"

这是因为
type
命令将保留UTF-8 BOM表,因此,当您组合具有BOM表的多个文件时,最终文件将在文件中间的不同位置包含多个BOM表

如果确定要合并的所有SQL文件都从BOM表开始,则可以使用以下脚本在实际合并它们之前从每个SQL文件中删除BOM表

这是通过管道化
类型的输出来完成的。管道的另一端将在3个
暂停
命令的帮助下使用前3个字节(BOM表)。每次暂停将消耗一个字节。流的其余部分将被发送到
findstr
命令,以将其附加到最终脚本中

由于SQL文件采用UTF-8编码,并且可能包含Unicode范围内的任何字符,因此某些代码页将干扰操作,并可能导致最终SQL脚本损坏

因此,已经考虑到这一点,批处理文件将使用代码页437重新启动,这对于访问任何二进制序列都是安全的

@echo off
setlocal DisableDelayedExpansion


setlocal EnableDelayedExpansion
for /F "tokens=*" %%a in ('chcp') do for %%b in (%%a) do set "CP=%%~nb"
if  !CP! NEQ 437 if !CP! NEQ 65001 chcp 437 >nul && (

    REM for file operations, the script must restatred in a new instance.
    "%COMSPEC%" /c "%~f0"

    REM Restoring previous code page
    chcp !CP! >nul
    exit /b
)
endlocal


set "RemoveUTF8BOM=(pause & pause & pause)>nul"
set "echoNL=echo("
set "FinalScript=C:\FinalScript\AllScripts.sql"

:: If you want the final script to start with UTF-8 BOM (This is optional)
:: Create an empty file in NotePad and save it as UTF8-BOM.txt with UTF-8 encoding.
:: Or Create a file in your HexEditor with this byte sequence: EF BB BF
:: and save it as UTF8-BOM.txt
:: The file must be exactly 3 bytes with the above sequence.
(
    type "UTF8-BOM.txt" 2>nul

    REM This assumes that all sql files start with UTF-8 BOM
    REM If not, then they will loose their first 3 otherwise legitimate characters.
    REM Resulting in a final corrupted script.
    for %%A in (*.sql) do (type "%%~A" & %echoNL%)|(%RemoveUTF8BOM% & findstr "^")

)>"%FinalScript%"

没有自动化的方法来做这件事吗?这个批处理文件在构建服务器进程的中间运行。您是否自动生成批处理文件?如果是,则将发电机配置为停止发出BOM。在这种情况下,您需要为Generators提供代码,是否没有自动化的方法?这个批处理文件在构建服务器进程的中间运行。您是否自动生成批处理文件?如果是,则将发电机配置为停止发出BOM。在这种情况下,您需要为没有BOM表的生成器“ANSI”提供代码。“ï»?是当您将带有BOM的UTF-8文件解释为ANSI文件时得到的结果。即使如此,它也应该只出现在文件的最开始处。但是你说你看到了“ï»»»在它发生的地方(复数),所以不仅仅是在第一行的开头。在这种情况下,它不是BOM表,而是不间断的零宽度空间。“ANSI”没有BOM表。“ï»?是当您将带有BOM的UTF-8文件解释为ANSI文件时得到的结果。即使如此,它也应该只出现在文件的最开始处。但是你说你看到了“ï»»»在它发生的地方(复数),所以不仅仅是在第一行的开头。在这种情况下,它不是BOM表,而是一个不间断的零宽度空间。