我有一个需要加载到数据库中的文件。它有一个管道 ( |
) 分隔符,但是每行包含不同数量的管道。使用批处理脚本,如何从每行中删除管道,以便每行上有相同数量的管道?
文件示例:
1|2|3||||||
4|5|6|||
7|8||||||
假设我只希望每行有 5 个管道,所以它看起来像:
1|2|3|||
4|5|6|||
7|8||||
我有一个需要加载到数据库中的文件。它有一个管道 ( |
) 分隔符,但是每行包含不同数量的管道。使用批处理脚本,如何从每行中删除管道,以便每行上有相同数量的管道?
文件示例:
1|2|3||||||
4|5|6|||
7|8||||||
假设我只希望每行有 5 个管道,所以它看起来像:
1|2|3|||
4|5|6|||
7|8||||
更新 请参阅第二个解决方案和限制更新。
示例 file.txt 内容
A|B|C|D|E|F|G
1|2|3|4|5|6|7
!|@|#|$|%|^|&
]1|]2|]3|]4|]5|]6|]7
|Two||Four||||Eight
!@$%^&%^*(){}|[]';/.,<>/|
Lonely||||||||||||||||||
Sep|er|ate| From| Th|e |W||orld | |
第一个解决方案
这是一种简单的方法来做你想做的事。特殊字符应该没有任何问题。
限制
%%A to %%Y
]
。for /F "tokens=1,* delims=]" %%Y in ('type file.txt ^| find /v /n ""') do (
为for /F "delims=" %%Z in ('type file.txt') do (
。只需指定要保留的列数和列。例如tokens=3-5,12,48-50
将仅选择列 3、4、5、12、48、49、50。确保添加或删除变量以匹配所需的输出。echo %%A^|%%B^|%%D^|%%C^|%%G^|%%E^|%%F
. 请注意,列也可以在 echo 语句中重新排序。
@echo off
setlocal DisableDelayedExpansion
for /F "delims=" %%Z in ('type file.txt') do (
for /F "tokens=1-5 delims=|" %%A in ("%%Z") do (
echo %%A^|%%B^|%%C^|%%D^|%%E
)
)
endlocal
pause >nul
您可以将 .bat 文件的输出重定向到新文件Script.bat>output.txt
,或者通过附加>>output.txt
到 echo 行将 echo 命令输出到文件。
示例输出:
A|B|C|D|E
1|2|3|4|5
!|@|#|$|%
]1|]2|]3|]4|]5
Two|Four|Eight|| <-- Note that this line exhibits limit 3.
!@$%^&%^*(){}|[]';/.,<>/|||
Lonely||||
Sep|er|ate| From| Th
第二种解决方案
仅共享限制1和4。目前在现有空白列中添加空格以保留所有列。它们可以通过进一步的代码更改来删除,但除非 OP 需要,否则不会添加。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%Z in ('type file.txt') do (
set "xLine=|%%Z"
call :Parse xLine
)
endlocal
pause >nul
goto :eof
:Parse
call set "xLine=%%%~1:||=| |%%"
for /F "tokens=1-5 delims=|" %%A in ("%xLine%") do (
echo %%A^|%%B^|%%C^|%%D^|%%E
)
goto :eof
示例输出:
A|B|C|D|E
1|2|3|4|5
!|@|#|$|%
]1|]2|]3|]4|]5
|Two| |Four|
!@$%^&%^*(){}|[]';/.,<>/|||
Lonely| | | |
Sep|er|ate| From| Th
没有直接的方法来实现这个过程,所以必须修改每个字符以便计算每行中的管道数。它工作,但它有点慢。
@echo off
setlocal EnableDelayedExpansion
rem Number of desired pipes
set limit=5
for /F "delims=" %%a in (input.txt) do (
set "line=%%a"
rem Get position of last character
set last=0
for /L %%b in (12,-1,0) do (
set /A "last|=1<<%%b"
for %%c in (!last!) do if "!line:~%%c,1!" equ "" set /A "last&=~1<<%%b"
)
rem Copy each character to result, but just %limit% number of pipes
set pipes=0
set result=
for /L %%c in (0,1,!last!) do (
if "!line:~%%c,1!" neq "|" (
set "result=!result!!line:~%%c,1!"
) else (
set /A pipes+=1
if !pipes! leq %limit% set "result=!result!|"
)
)
echo !result!
)
如果输入行包含感叹号,以前的程序将失败。
输出:
1|2|3|||
4|5|6|||
7|8||||
安东尼奥