从每行文件中删除多个分隔符

时间:2013-01-09 12:29:22

标签: batch-file

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

档案示例:

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

假设我只想在每一行上设置5个管道,所以它看起来像:

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

2 个答案:

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

第一个解决方案

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

限制

  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. 不保留文件中的空白行。 (如果需要,可以修复。)
  5. 只需指定要保留的列数和列数。例如,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||||

安东尼奥