批处理脚本从文件中删除 BOM ()
Batch script remove BOM () from file
我创建了一个批处理脚本,用于将文件夹中的 SQL 个文件复制到一个大的 SQL 脚本中。问题是当我 运行 这个 SQL 脚本出现错误
Incorrect syntax near ''
我将一个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++ 上的菜单项略有不同
正如 MSalters 在他的评论中已经提到的,根据 wikipedia 
是 UTF8 BOM 的 ANSI 表示。
PowerShell 比批处理更适合处理编码任务:
## Q:\Test18\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
为基本部分调用 powershell 的批处理:
:: Q:\Test18\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 开始,然后您可以使用以下脚本从每个文件中删除 BOM,然后再实际合并它们。
这是通过管道 type
的输出来完成的。管道的另一端将在 3 pause
命令的帮助下消耗前 3 个字节(BOM)。每个 pause
将消耗一个字节。流的其余部分将发送到 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%"
TypeWithoutBOM.bat
@echo off
set "RemoveUTF8BOM=(pause & pause & pause)>nul"
type %1|(%RemoveUTF8BOM% & findstr "^")
此批处理文件的工作方式与 type
命令类似,但会删除显示的文件的前 3 个字节。
用法:TypeWithoutBOM UTF8-file.txt > newfile.txt
我创建了一个批处理脚本,用于将文件夹中的 SQL 个文件复制到一个大的 SQL 脚本中。问题是当我 运行 这个 SQL 脚本出现错误
Incorrect syntax near ''
我将一个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++ 上的菜单项略有不同
正如 MSalters 在他的评论中已经提到的,根据 wikipedia 
是 UTF8 BOM 的 ANSI 表示。
PowerShell 比批处理更适合处理编码任务:
## Q:\Test18\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
为基本部分调用 powershell 的批处理:
:: Q:\Test18\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 开始,然后您可以使用以下脚本从每个文件中删除 BOM,然后再实际合并它们。
这是通过管道 type
的输出来完成的。管道的另一端将在 3 pause
命令的帮助下消耗前 3 个字节(BOM)。每个 pause
将消耗一个字节。流的其余部分将发送到 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%"
TypeWithoutBOM.bat
@echo off
set "RemoveUTF8BOM=(pause & pause & pause)>nul"
type %1|(%RemoveUTF8BOM% & findstr "^")
此批处理文件的工作方式与 type
命令类似,但会删除显示的文件的前 3 个字节。
用法:TypeWithoutBOM UTF8-file.txt > newfile.txt