返回列表 发帖

[文本处理] 【已解决】求助批处理提取特定文本并分列

本帖最后由 jave000 于 2021-9-10 10:12 编辑

同类搜索简述:
按创建和修改时间将一批文本文件,从一个文件夹批量复制到另一个文件夹,并且两个文件夹的路径中间都有一个变量,需要手动输入,以及其中一个路径涉及到桌面,但为了可以分享给同事使用,识别任意电脑名下的桌面路径。
同时对所有文本的内容,筛出以序号为行首的内容,并对其进行分列,再转换到csv文件,同时增加一列生成其文本文件名。
同时自动打开excel。
复杂度:多行文本在分列后,同一列的部分内容要归入同一个单元格。其中部分列的内容只有一行。
感谢楼下诸位

@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" & exit /b
set-location $PSScriptRoot
$jave = read-host "roject Model Folder"
$CXMPV = [Environment]::GetFolderPath("Desktop")
$order = "2,3,4,5,6,1"
$sour = "\\btssvr9\pds1\$jave\3d\\iso_dgn\MOC_2021\"
$dest = "$CXMPV\Print\"
do
{
    $minute = read-host "Minutes of Minutes"
    $minute = $minute.trim()
}
while ($minute -match "\D")
Get-ChildItem -Path $sour -File |
    Where-Object { ($_.CreationTime -gt (get-date).AddMinutes(-$minute)) -or ($_.LastWriteTime -gt (get-date).AddMinutes(-$minute)) } |
    foreach-object {
        write-host $_.fullname
        copy-item $_.fullname -Destination $dest
    }
Invoke-Item $sour
Remove-Item $dest* -Include z-mto.csv
if (-not ([string]::IsNullOrEmpty($args[0])))
{
    $sour = $args[0]
}
function zget-data()
{
    [System.Collections.ArrayList] $sirenas = @()
    $rem = "^\s{3}\d{1}|^\s{2}\d{2}|^\s{11,12}\S.+"
    $renfs = "(\w{4})(\w{1,4})?(\w{1,4})?(\w{1,5})?(.*)"
    $renfd = "`$1-`$2-`$3-`$4-`$5"
    $res = "`n(.{4})(.{46})(.{13})(.{15})(.+)((?:`n\s{11,12}.+)*)"
    #$res = "`n\s{2,3}(\d{1,2})\s{4,}(\S.+?\S)\s{2,}(\d+(?:X\d+)?)\s{2,}(\S+(?:\s\S+)*)\s{2,}(\d+(?:[.]\d+)?(?:\sM)?)((?:`n\s{11,12}.+)*)"
    $red = "`t`$1`t`$2`$6`t`$3`t`$4`t`$5::"
    Get-ChildItem -path $sour "*.prt" | foreach-object {
        write-host "  "$_.basename
        $nf = $_.basename.ToUpper() -replace $renfs,$renfd -replace "-+$","";
        $a = "`n" + ((get-content -Encoding utf8 -path $_.fullname ) -match $rem -join "`n") ;
        if ( $a.length -gt 1 )
        {
            $a = $a -replace $res,$red -replace "[ `n]+"," " -replace " *`t *","`t"
            $a = $a -replace ":","" -replace "::","`n" -replace "(?m)\sm$","" -replace "(?m)^(?=`t)",$nf
            $sirenas.add($a) | out-null
        }
    }
    $sirenas = $sirenas -split "`n"
    $reos = "^([^`t]*)`t([^`t]*)`t([^`t]*)`t([^`t]*)`t([^`t]*)`t([^`t]*)$"
    $reod = $order -replace ",","`t" -replace "(?=\d)","`$"
    $sirenas = $sirenas -replace $reos, $reod
    return $sirenas
}
function zout-csv()
{
    $reos = "^([^`t]*)`t([^`t]*)`t([^`t]*)`t([^`t]*)`t([^`t]*)`t([^`t]*)$"
    $reod = '"$1","$2","$3","$4","$5","$6"'
    $sirenas -replace $reos,$reod | out-file -encoding utf8 ($dest + "z-mto.csv")
}
function zout-excel()
{
    try
    {
        $Excel = New-Object -ComObject Excel.Application  -ErrorAction Stop
    }
    catch
    {
        return
    }
    $Excel.Visible = $true
    $Workbook = $Excel.Workbooks.Add()
    $Sheet = $Workbook.Worksheets.Item(1)
    $v = [string[,]]::new($sirenas.count,1)
    for ( $i =0 ; $i -lt $sirenas.count ; $i++ )
    {
        $v[$i,0] = $sirenas[$i]
    }
    $rng = "A1:A" +  $sirenas.count
    $Sheet.range($rng).value2 = $v
    $colA = $sheet.range("A1").EntireColumn
    $colrange = $sheet.range("A1")
    $colA.texttocolumns($colrange,1,1,$false,$true,$false,$false,$false) | out-null
    $sheet.columns.autofit() | out-null
    $Workbook.SaveAs(($PSScriptRoot + "\" + $dest))
    $excel.Quit()
    [system.GC]::Collect()
}
[System.Collections.ArrayList] $sirenas = @()
$sirenas = zget-data
zout-csv
zout-excel

回复 2# jave000


    请上传到网盘试试
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

上传网盘内容最好有:
1.源文件
2.每个步骤中,文件处理后的示范样式。

TOP

本帖最后由 newswan 于 2021-6-23 14:39 编辑

基本看明白了,用excel做比较好

处理1个文件
powershell
$file = "1.txt"
$fc = get-content $file
$i = 0
while ($i -le $fc.count)
{
    if ($fc[$i] -match "^\s\s\s\d\s|^\s\s\d\d\s")
    {
        $a = $fc[$i] -split "\s\s\s*"
        $a[5] = $a[5] -replace "\sm",""
        while ($fc[$i+1] -match "^\s{11}\S")
        {
            $a[2] = $a[2] + " " + $fc[$i+1].trim()
            $i += 1
        }
        if (-not ($fc[$i+1] -match "^\s{11}\S"))
        {
            $a
        }
    }
    $i += 1
}COPY
1

评分人数

TOP

本帖最后由 newswan 于 2021-6-23 13:46 编辑

4 楼样本 提取结果
1
PIPE, SMLS, HG/T 20553, ASTM A312 TP316L, SAWN END, CS 1000-27, DN200 - 219.1 X 4
200
I512912
2.1
2
PIPE, SMLS, HG/T 20553, ASTM A312 TP316L, SAWN END, CS 1000-27, DN150 - 168.3 X 3.6
150
I512911
1.6
3
PIPE, SMLS, HG/T 20553, ASTM A312 TP316L, SAWN END, CS 1000-27, DN50 - 60.3 X 2.9
50
I512906
0.3
4
PIPE, SMLS, HG/T 20553, ASTM A312 TP316L, SAWN END, CS 1000-27, DN25 - 33.7 X 2.6
25
I512903
0.3
5
PIPE, SMLS, HG/T 20553, ASTM A312 TP316L, SAWN END, CS 1000-27, DN20 - 26.9 X 2
20
I512902
0.2
6
CONCENTRIC REDUCER, SMLS, GB/T 12459, R(C), ASTM A312 TP316L, WELD PREP. ACC. TO CS 416, ENDPREP. ACC. TO CS 416, CS 1000-28, DN200 X 150 - 219.1 X 4/168.3 X 3.6
200X150
I512654
1
7
ELBOW 90 C, SMLS, GB/T 12459, 90E(L), ASTM A312 TP316L, WELD PREP. ACC. TO CS 416, CS 1000-28, DN200 - 219.1 X 4
200
I512504
1
8
ELBOW 90 C, SMLS, GB/T 12459, 90E(L), ASTM A312 TP316L, WELD PREP. ACC. TO CS 416, CS 1000-28, DN50 - 60.3 X 2.9
50
I512498
1
9
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN10, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN200 - 219.1 X 4
200
I512820
1
10
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN16, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN150 - 168.3 X 3.6
150
I512819
1
11
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN16, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN50 - 60.3 X 2.9
50
I512814
1
12
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN40, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN25 - 33.7 X 2.6
25
I512799
1
13
BLIND FLANGE, EN 1092-1, TYPE 05, SA 182 F316L, PN40, CONTACT FACE- FORM A EN 1092-1, CS 1000-37, DN25
25
I512946
1
14
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN40, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN20 - 26.9 X 2
20
I512798
1
15
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN16,  WN 1000-841 DN 200 THICKNESS 1.6
200
I224625
1
16
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN16,  WN 1000-841 DN 150 THICKNESS 1.6
150
I224624
2
17
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN40,  WN 1000-841 DN 50 THICKNESS 1.6
50
I224645
1
18
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN40,  WN 1000-841 DN 25 THICKNESS 1.6
25
I224638
2
19
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN40,  WN 1000-841 DN 20 THICKNESS 1.6
20
I224636
1
20
SCREWED CONNECTION, DIN EN ISO 4017/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M20 X 70
20
I91453
16
21
SCREWED CONNECTION, DIN EN ISO 4017/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M20 X 75
20
I91454
8
22
SCREWED CONNECTION, DIN EN ISO 4014/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M16 X 65
16
I91413
4
23
SCREWED CONNECTION, DIN EN ISO 4014/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M12 X 50
12
I91371
4
24
SCREWED CONNECTION, DIN EN ISO 4014/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M12 X 55
12
I91372
8
25
ERROR READING SPECIALTY MATERIAL DESCRIPTION LIBRARY
150
V710RE11F3121
1
26
SLIDE SHOE SIDE MOVABLE COMPANY STD WN8205-2 TYPE 5 (INS.-THK. 120 MM), UST37-2 WITH COATING COMPANY STANDARD WN 8110, SHOE-LENGTH 300 MM, CLAMPED
200
S0W-200
1
1
PIPE, SMLS, HG/T 20553, ASTM A312 TP316L, SAWN END, CS 1000-27, DN250 - 273 X 4
250
I512913
0.5
2
CONCENTRIC REDUCER, SMLS, GB/T 12459, R(C), ASTM A312 TP316L, WELD PREP. ACC. TO CS 416, ENDPREP. ACC. TO CS 416, CS 1000-28, DN250 X 200 - 273 X 4/219.1 X 4
250X200
I512658
1
3
ELBOW 90 C, SMLS, GB/T 12459, 90E(L), ASTM A312 TP316L, WELD PREP. ACC. TO CS 416, CS 1000-28, DN250 - 273 X 4
250
I512505
1
4
BLIND DISC, CS 473 PN 10 SERIES 2, SA 240 316L, FLANGE MOUNTING DIMENSION, PN10, CLAMPED PART CONTACT FACE FORM A DIN EN 1092-1, CS 1000-33, DN200
200
I512980
1
5
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN10, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN250 - 273 X 4
250
I512821
1
6
WELDNECK FLANGE, EN 1092-1, TYPE 11, SA 182 F316L, PN10, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, ENDPREP. ACC. TO CS 416, CS 1000-34, DN200 - 219.1 X 4
200
I512820
2
7
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN10,  WN 1000-841 DN 250 THICKNESS 1.6
250
I224614
1
8
GASKET, DIN EN 1514-1-IBC, NQ, 1.4401/GRAPHITE/1.4571, PN16,  WN 1000-841 DN 200 THICKNESS 1.6
200
I224625
3
9
SCREWED CONNECTION, DIN EN ISO 4017/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M20 X 75
20
I91454
8
10
SCREWED CONNECTION, DIN EN ISO 4014/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M20 X 85
20
I91456
8
11
SCREWED CONNECTION, DIN EN ISO 4014/4032, A2-70, CS 1000-16, NUT (H=0.9XD) M20 X 80
20
I91455
12
12
BELLOWS SEAL VALVE, HANDWHEEL, CLIMBING, V2436W, 1.4581, 1.4571, 1.4408, 1.4404, PN10, FLANGE CONTACT FACE TO FORM B1 DIN EN 1092-1, WN 8480, DN 200
200
I372364
1COPY

TOP

回复 8# newswan


十分感谢,我试了一下,基本成功运行(元件描述中出现了很多string Trim(Params char[] trimChars), string Trim() string Trim(Params char[] trimChars), string Trim())。
只是结果我用不起来,希望批处理能完成提取NO        DESCRIPTION AND SPECIFICATION        (MM)          ARTICLE-NO        QTY这五列的正文内容,将其分别放入对应的单元格,其中DESCRIPTION AND SPECIFICATION这一列需要将原来的各行合并起来(我看你的代码已经实现了,本来以为做不到所以我一开始就没提,惊为天人),并且依然保持按列排序(必须排成五列)。其他内容我一概不要。
好像bat是不能保存excel文件的吧?我也不知道txt怎么实现,如果结果不能直接变成excel的单元格,我也希望将结果手动复制过去后能自动分布到excel的五列里。
我后面还要继续将结果合并ARTICLE-NO列的重复项,并将QTY列的“ M”删除,以及将重复项的数据求和。(这是最终结果,但上一步未分重复项的结果我也是要的,便于后期校核数据是否遗漏。)
另外powershell我很陌生,刚才也是摸索着用的,没想到复制代码过去,只是右击,就自动粘贴了,它生成结果后没有保存成文件,是代码里没写这一段还是不支持?好像使用起来没有bat方便,bat我只要放到相应文件夹双击就直接出来结果了,适合分享给其他同事。

TOP

回复 5# Batcher


    管理员好,我是在公司发的,公司屏蔽了所有网盘的网址,我实在上传不了,这里的附件我也上传不了,无论是zip还是txt,都是失败
我试试把文本发到邮箱,晚上从自己电脑发过来。
谢谢

TOP

本帖最后由 newswan 于 2021-6-23 14:45 编辑

回复 10# jave000


    改一下啊,trim 必须带括号  trim()

选其中一句,插入为第一行,保存为bat
@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" & exit /b
@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" & pause & exit
#&cls&@Powershell "& {[ScriptBlock]::Create("'#' + (gc '%~f0' -raw)").Invoke()}" & pause & exit
#&cls&@Powershell "& {[ScriptBlock]::Create("'#' + ([io.file]::ReadAllText('%~f0',[text.encoding]::Default))").Invoke()}" & pause & exit
#&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" & pause&exitCOPY

TOP

回复 9# idwma


    谢谢,运行结果很好,就是特别的慢,每一行数据跳出一个闪烁窗口,一秒大约生成两三行数据,数据都在cmd里,然后手动复制到excel对么?但是我任意键就自动关闭了……

TOP

本帖最后由 newswan 于 2021-6-23 14:51 编辑
$fileSour = "1.txt"
$fileDest = "11.txt"
$fc = get-content $fileSour
[System.Collections.ArrayList] $da = @()
$i = 0
while ($i -le $fc.count)
{
    if ($fc[$i] -match "^\s\s\s\d\s|^\s\s\d\d\s")
    {
        $a = $fc[$i] -split "\s\s\s*"
        $a[5] = $a[5] -replace "\sm",""
        while ($fc[$i+1] -match "^\s{11}\S")
        {
            $a[2] = $a[2] + " " + $fc[$i+1].trim()
            $i += 1
        }
        if (-not ($fc[$i+1] -match "^\s{11}\S"))
        {
            $da.add($a -join "`t") | out-null
        }
    }
    $i += 1
}
$da | out-file $fileDestCOPY

TOP

处理目录下多个文件
$pathSour = "a"
$fileDest = "11.txt"
[System.Collections.ArrayList] $da = @()
get-childitem -path $pathSour *.rpt | foreach-object {
    $fc = get-content $_
    $i = 0
    while ($i -le $fc.count)
    {
        if ($fc[$i] -match "^\s\s\s\d\s|^\s\s\d\d\s")
        {
            $a = $fc[$i] -split "\s\s\s*"
            $a[5] = $a[5] -replace "\sm",""
            while ($fc[$i+1] -match "^\s{11}\S")
            {
                $a[2] = $a[2] + " " + $fc[$i+1].trim()
                $i += 1
            }
            if (-not ($fc[$i+1] -match "^\s{11}\S"))
            {
                $da.add($a -join "`t") | out-null
            }
        }
        $i += 1
    }
}
$da | out-file $fileDestCOPY

TOP

文件是 prt 还是 rpt ?

TOP

回复 14# newswan


    复制到excel已经是自动分列了,感谢你给我涨了知识。
出现了两处识别错误:

第一个是蝶阀,HAND LEVER, K2560C出现的位置不对,而且中间多了个空格,导致复制到excel后,后面两列错位,猜测是因为BUTTERFLY  VALVE中间有两个空格,这是我们数据库管理员输入描述有误,不知道是否能解决这种偶尔出现多个空格的BUG,毕竟真正用来分列的空格起码超过五个,能否设置小于三个的不算。
  17    BUTTERFLY  VALVE, HAND LEVER, K2560C,     100          IC02606            1
           NEOTECHA TYPE -TRIM N07,
           EN-GJS-400-18U-LT/PTFE, PN10, SCREW
           IN HOLE, CONTACT FACE FORM B1 DIN EN
           1092-1, INTEGR.GASKET, WN 8480, DN
           100

        17        BUTTERFLY NEOTECHA TYPE -TRIM N07, EN-GJS-400-18U-LT/PTFE, PN10, SCREW IN HOLE, CONTACT FACE FORM B1 DIN EN 1092-1, INTEGR.GASKET, WN 8480, DN 100        VALVE, HAND LEVER, K2560C,        100        IC02606        1


第二个是弯管,同样的BUG,两个空格导致识别错误。关于数量这里的“ M”我也不清楚能不能删,会不会干扰到描述里万一也有这样的字符,如果不行,我手动处理。
   3    PIPE BEND,  RADIUS 2,5 X D, WN 9900-1,    80           I302777           0.4 M
           H2/1.4404, SAWN END, - DN 80 - 88.9 X
           2.3

        3        PIPE BEND, H2/1.4404, SAWN END, - DN 80 - 88.9 X 2.3        RADIUS 2,5 X D, WN 9900-1,        80        I302777        0.4 M

TOP

本帖最后由 newswan 于 2021-6-23 15:25 编辑

回复 19# jave000

    改这一句,4个空格分列
$a = $fc[$i].trim() -split "\s{4,}*"COPY

TOP

本帖最后由 newswan 于 2021-6-23 15:39 编辑

如果 保留m ,删除这一句
$a[-1] = $a[-1] -replace "\sm",""COPY

TOP

返回列表