0

我有一个需要加载到数据库中的文件。它有一个管道 ( |) 分隔符,但是每行包含不同数量的管道。使用批处理脚本,如何从每行中删除管道,以便每行上有相同数量的管道?

文件示例:

1|2|3||||||  
4|5|6|||  
7|8||||||  

假设我只希望每行有 5 个管道,所以它看起来像:

1|2|3|||  
4|5|6|||  
7|8||||
4

2 回答 2

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 | |

第一个解决方案

这是一种简单的方法来做你想做的事。特殊字符应该没有任何问题。

限制

  1. 它目前只支持最多24 25 列。%%A to %%Y
  2. 第一个值可能不以 开头]替换for /F "tokens=1,* delims=]" %%Y in ('type file.txt ^| find /v /n ""') do (for /F "delims=" %%Z in ('type file.txt') do (
  3. “空”字段只能出现在每行的末尾。见第二个解决方案。
  4. 不保留文件中的空行。(如果需要,可以修复此问题。)

只需指定要保留的列数和列。例如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

第二种解决方案

仅共享限制14。目前在现有空白列中添加空格以保留所有列。它们可以通过进一步的代码更改来删除,但除非 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
于 2013-01-10T03:43:28.363 回答
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||||

安东尼奥

于 2013-01-09T23:06:07.787 回答