我有一个文件需要加载到数据库中。它有一个管道分隔符(|
),但每行包含不同数量的管道。使用批处理脚本,如何从每一行中删除管道,以便每行都有相同数量的管道?
档案示例:
1|2|3||||||
4|5|6|||
7|8||||||
假设我只想在每一行上设置5个管道,所以它看起来像:
1|2|3|||
4|5|6|||
7|8||||
答案 0 :(得分:2)
更新请参阅第二个解决方案和限制更新。
示例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命令输出到文件。
示例输出:
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
答案 1 :(得分:1)
没有直接的方法来实现这个过程,因此必须修改每个字符以计算每行中的管道数量。它有效,但有点慢。
@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||||
安东尼奥