Board logo

标题: [文本处理] 批处理for命令如何按指定长度截取列? [打印本页]

作者: shootman2    时间: 2018-6-8 22:32     标题: 批处理for命令如何按指定长度截取列?

现在工作中遇到一个问题,需要将文本导入到数据库中,文本内容如下:

要求是将数据分成6个字段入库,但是貌似不能用空格分割。
最后一行比较有代表性,其中从(USA)到最后一个NA是属于第二个字段的。

求助大神帮忙看看,给个思路也行!
作者: yhcfsr    时间: 2018-6-8 23:14

本帖最后由 yhcfsr 于 2018-6-8 23:24 编辑

最好有数据样本,原数据列之间的分隔符是空格??而字段二内有空格,所以不能用空格分离??
思路:规律是,字段都是对齐的,所以通过字符串截取,可以获取字段内容。当然这种方法,字段尾的空格也会截进来,再想办法去掉尾巴的空格就行。
powershell能够轻松实现,BAT会麻烦些。
作者: shootman2    时间: 2018-6-8 23:28

回复 2# yhcfsr


    那可以安装长度来截取吗?比如第一个字段,从行首开始截取13个字符,第二个字段从14开始截取24个字符这样
作者: yhcfsr    时间: 2018-6-8 23:33

本帖最后由 yhcfsr 于 2018-6-8 23:36 编辑

回复 3# shootman2

对,我就是这个意思.
因为同一个字段,有效内容长度不一样,不能用替换空格的方法来实现分割.
作者: shootman2    时间: 2018-6-8 23:34

回复 4# yhcfsr


    bat批处理可以这样实现吗?
作者: yhcfsr    时间: 2018-6-8 23:37

回复 5# shootman2
可以,只不过去掉尾巴的空格,要从字段尾逐字判断,可能会稍微影响效率.
作者: taofan712    时间: 2018-6-9 01:05

提供一个思路,就用空格符为分隔符,每一列依次赋值存储到变量。
取第1列和倒数4列后,清空对应变量。再将剩余变量组合成第二列。
即可将每行内容分6字段。
作者: shootman2    时间: 2018-6-9 14:22

回复 6# yhcfsr


    我研究了一下,好像可以通过gawk去实现,
    gawk "{print substr($0,1,12)""substr($0,13,14);}" 123.txt

    但是又遇到了新问题,在print的时候,我想在substr($0,1,12)和substr($0,13,14)之间增加一个|进行连接,但是怎么弄都不行,看大神你有没有好方法?
作者: yhcfsr    时间: 2018-6-9 14:40

本帖最后由 yhcfsr 于 2018-6-9 14:47 编辑

哈哈,我发两个脚本你看看。注意备份源文件,POWERSHELL的修改是直接覆盖源文件的。
输出的文件用EXCEL打开,可以直观查看6列数据。
POWERSHELL强大的正则,不需要截取去尾这些操作。
  1. $sf='D:\test\data.txt';
  2. $content=gc -LiteralPath $sf;
  3. $output=$null;
  4. foreach($line in $content){
  5.    
  6.     $output+=($line -replace '(\d+)\s*.*','$1')+"`t";
  7.     $output+=($line -replace '.*(\(USA\).*NA).*','$1')+"`t";
  8.     $output+=($line -replace '.*NA\s*(\d+)\s*.*','$1')+"`t";
  9.     $output+=($line -replace '.*NA\s*\d+\s*(\d+)\s*.*','$1')+"`t";
  10.     $output+=($line -replace '.*NA\s*\d+\s*\d+\s*(\d+)\s*.*','$1')+"`t";
  11.     $output+=($line -replace '.*\s*(\d+)$','$1')+"`r`n";
  12. }
  13. $output>$sf;
复制代码
BAT
字符串截取的数值设置,需要根据源数据具体情况,自行调试。
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "delims=" %%a in ('type data.txt') do (
  3.         set "str=%%a"
  4.         
  5.         set "colum1=!str:~,12!"
  6.         call:TrimEnd "!colum1!" colum1 " "
  7.         
  8.         set "colum2=!str:~12,24!"
  9.         call:TrimEnd "!colum2!" colum2 " "
  10.         
  11.         set "colum3=!str:~36,3!"
  12.         call:TrimEnd "!colum3!" colum3 " "
  13.         
  14.         set "colum4=!str:~39,11!"
  15.         call:TrimEnd "!colum4!" colum4 " "
  16.         
  17.         set "colum5=!str:~50,2!"
  18.         call:TrimEnd "!colum5!" colum5 " "
  19.         
  20.         set "colum6=!str:~52!"
  21.         call:TrimEnd "!colum6!" str " "
  22.         call echo;!colum1!        !colum2!        !colum3!        !colum4!        !colum5!        !colum6!
  23. ))>out.txt
  24. endlocal&pause&exit
  25. :TrimEnd (源字符串,输出字符串,要删除的尾字符)去尾
  26. setlocal
  27. if "%~1" neq "" (set "var=%~1") else endlocal&goto:eof
  28. :lp
  29. if "%var:~-1%" equ "%~3" set "var=%var:~,-1%"&goto:lp
  30. endlocal&set "%2=%var%"&goto:eof
复制代码

作者: Batcher    时间: 2018-6-9 14:48

换一个思路:导入Excel,按照宽度分列
作者: zaqmlp    时间: 2018-6-9 15:39

  1. powershell "gc 'a.txt'|%%{if($_.trim() -match '(\S+)\s+?(\S+(?:\s+\S+)*)\s+?(\S+)\s+?(\S+)\s+?(\S+)\s+?(\S+)'){$matches[1..6] -join ','}}"
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2