用于识别特定文本并替换为另一列中的文本而不影响列位置的脚本 [英] Script to identify specific text and replace with text from another column without effecting column position

查看:22
本文介绍了用于识别特定文本并替换为另一列中的文本而不影响列位置的脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .txt 文件,其中包含从特定列号开始的文本组织的各种数据行 - 基本上是一个数据表.

以下示例显示了每列的开始位置:

我希望脚本在第 555 列中查找包含-"的所有行,并将其替换为第 450 列中的前 19 个字符,而不影响任何行间距.

此示例所需的输出:

如您所见,Brooklyn"已从第 450 列复制并替换了第 555 列中的-".

<块引用>

请注意:

  • 脚本将需要运行位于同一文件夹中的多个 .txt 文件
  • .txt 文件包含不同数量的行,例如某些文件可能有 20 行,而其他文件可能有 100 行

此外,关于检查给定文件夹中的每个 .txt - 我将使用以下内容.如果可能的话,请告诉我.

Get-ChildItem C:\Users\Desktop -Filter *.txt |ForEach-Object {设置内容 $_.FullName) }

有人可以帮忙在 PowerShell 中编写脚本吗.

先谢谢你!

解决方案

这确实相当丑陋,但似乎可以解决问题.[咧嘴笑]

<预><代码><#_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789#>$InStuff = @'阿尔法布拉沃 - Delta Echo - - Foxtrot GolfHotel Inkblot Joker - Kilo - Lima Mike Nova'@ -split [环境]::NewLine$ColSize = 10$ColToCheck = 30$TriggerText = '-'$SourceCol = 10$DestCol = 60$SourceStopIndex = $SourceCol + $ColSize - 1foreach($InStuff 中的 $IS_Item){if ($IS_Item[$ColToCheck] -eq $TriggerText){$SourceText = -join $IS_Item[$SourceCol..$SourceStopIndex]$IS_Item$IS_Item.Remove($DestCol, $ColSize).Insert($DestCol, $SourceText)}}

输出...

Hotel Inkblot Joker - Kilo - Lima Mike NovaHotel Inkblot Joker - Kilo - Inkblot Mike Nova

它的作用...

  • 找到触发文本
  • 复制源文本
  • 删除当前目标文本
  • 插入替换上述内容
<小时>

根据要求,这里有一个完整的脚本来处理读取文件 &写出更改.它不会覆盖源文件,但注释会告诉人们如何进行更改.

# 创建一些测试文件$FileOneText = @'阿尔法布拉沃 - Delta Echo - - Foxtrot GolfHotel Inkblot Joker - Kilo - Lima Mike Nova'@ |设置内容$env:TEMP\Jasdeep_01.txt"$FileTwoText = @'Alfa Bravo - - Delta - Echo Foxtrot GolfHotel Inkblot Joker - Kilo - Lima Mike Nova'@ |设置内容$env:TEMP\Jasdeep_02.txt"$FileThreeText = @'阿尔法布拉沃 - Delta Echo Foxtrot Golf Hotel InkblotJoker Kilo Lima - Mike Nova Oscar Papa Quebec'@ |设置内容$env:TEMP\Jasdeep_03.txt"$ColSize = 10$ColToCheck = 30$TriggerText = '-'$SourceCol = 10$DestCol = 60$SourceDir = $env:TEMP$Filter = 'Jasdeep*.txt'$FileList = Get-ChildItem -LiteralPath $SourceDir -Filter $Filter -Fileforeach ($FileList 中的 $FL_Item){$ChangedContent = foreach ($Line in (Get-Content -LiteralPath $FL_Item.FullName)){if ($Line[$ColToCheck] -eq $TriggerText){$SourceText = $Line.Substring($SourceCol, $ColSize)$Line.Remove($DestCol, $ColSize).Insert($DestCol, $SourceText)}别的{$行}}# 为了测试,我使用了新文件来保存更改$NewFileName = $FL_Item.FullName -replace $FL_Item.BaseName, ('{0}_{1}' -f $FL_Item.BaseName, 'Changed')# 注释掉上面的行 &# 如果要替换原件,请取消注释下一行#$NewFileName = $FL_Item.FullName$ChangedContent |设置内容 -LiteralPath $NewFileName}

I have a .txt file that contains various lines of data which is organised by text starting at specific column numbers - basically a table of data.

The below example shows where each column starts:

I would like the script to find all lines which contain "-" in column 555 and replace this with the first 19 characters found in column 450 without effecting any line spacing.

Desired output for this example:

As you can see "Brooklyn" has been copied from column 450 and replaced the "-" in column 555.

Please note:

  • The script will need to run through multiple .txt files located in the same folder
  • The .txt files contain various number of lines e.g some files might have 20 lines whereas others may have 100

Also, In regards to checking each .txt in a given folder - I will be using the below. Please let me know if it possible with this.

Get-ChildItem C:\Users\Desktop -Filter *.txt | 
ForEach-Object { 
Set-Content $_.FullName) }

Could someone please help with scripting this in PowerShell.

Thank you in advance!

解决方案

this is really rather ugly, but it seems to do the job. [grin]

<#
_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#>

$InStuff = @'
Alfa      Bravo     -         Delta     Echo      -         -         Foxtrot   Golf
Hotel     Inkblot   Joker     -         Kilo      -         Lima      Mike      Nova
'@ -split [environment]::NewLine

$ColSize = 10
$ColToCheck = 30
$TriggerText = '-'
$SourceCol = 10
$DestCol = 60
$SourceStopIndex = $SourceCol + $ColSize - 1

foreach ($IS_Item in $InStuff)
    {
    if ($IS_Item[$ColToCheck] -eq $TriggerText)
        {
        $SourceText = -join $IS_Item[$SourceCol..$SourceStopIndex]

        $IS_Item
        $IS_Item.Remove($DestCol, $ColSize).Insert($DestCol, $SourceText)
        }
    }

output ...

Hotel     Inkblot   Joker     -         Kilo      -         Lima      Mike      Nova
Hotel     Inkblot   Joker     -         Kilo      -         Inkblot   Mike      Nova

what it does ...

  • finds the trigger text
  • copies the source text
  • removes the current destination text
  • inserts the replacement for the above

as requested, here's a full script that handles reading the files & writing out the changes. it does NOT overwrite the source files, but the comments tell one how to make that change.

# create some testing files
$FileOneText = @'
Alfa      Bravo     -         Delta     Echo      -         -         Foxtrot   Golf
Hotel     Inkblot   Joker     -         Kilo      -         Lima      Mike      Nova
'@ | Set-Content "$env:TEMP\Jasdeep_01.txt"
$FileTwoText = @'
Alfa      Bravo     -         -         Delta     -         Echo      Foxtrot   Golf
Hotel     Inkblot   Joker     -         Kilo      -         Lima      Mike      Nova
'@ | Set-Content "$env:TEMP\Jasdeep_02.txt"
$FileThreeText = @'
Alfa      Bravo     -         Delta     Echo      Foxtrot   Golf      Hotel     Inkblot
Joker     Kilo      Lima      -         Mike      Nova      Oscar     Papa      Quebec
'@ | Set-Content "$env:TEMP\Jasdeep_03.txt"

$ColSize = 10
$ColToCheck = 30
$TriggerText = '-'
$SourceCol = 10
$DestCol = 60

$SourceDir = $env:TEMP
$Filter = 'Jasdeep*.txt'

$FileList = Get-ChildItem -LiteralPath $SourceDir -Filter $Filter -File

foreach ($FL_Item in $FileList)
    {
    $ChangedContent = foreach ($Line in (Get-Content -LiteralPath $FL_Item.FullName))
        {
        if ($Line[$ColToCheck] -eq $TriggerText)
            {
            $SourceText = $Line.Substring($SourceCol, $ColSize)

            $Line.Remove($DestCol, $ColSize).Insert($DestCol, $SourceText)
            }
            else
            {
            $Line
            }
        }
    # for testing, i used new files for saving the changes
    $NewFileName = $FL_Item.FullName -replace $FL_Item.BaseName, ('{0}_{1}' -f $FL_Item.BaseName, 'Changed')
    #    comment out the line above &
    #    UN-comment the next line if you want to replace the originals
    #$NewFileName = $FL_Item.FullName
    $ChangedContent |
        Set-Content -LiteralPath $NewFileName
    }

这篇关于用于识别特定文本并替换为另一列中的文本而不影响列位置的脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆