如何在 Powershell 中一次替换多个 .txt 文件中的数据? [英] How can i replace data in multiple .txt files at once in Powershell?

查看:67
本文介绍了如何在 Powershell 中一次替换多个 .txt 文件中的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个文件夹中有多个 .txt 文件,这些文件具有特定的数据格式,其中每一行都从 3 位数字开始,例如.

I have multiple .txt files in a folder, which have a specific data format in which every line, starts from 3 digit numbers, example say.

101,3333,35899,BufferC1,99,02,333
102,3344,30079,BufferD2,89,03,444
.... and so on.

现在,如果记录以101"开头,那么我必须替换第 3 个 &与一些文本同一行的第 5 个索引元素.替换完所有文件后,我必须将所有修改过的文件复制到同一台机器上的另一个目录/文件夹中.

Now, if the record starts with "101", then I have to replace the 3rd & 5th index element of the same line with some text. Once all files are replaced, then I have to copy all modified files to another directory/folder on the same machine.

我写了一些不起作用的代码.请帮助我,因为我是 powershell 的新手.我是否正在采用正确的方法?

I have written some code which is not working. Please help me as I am a newbie in powershell. Am I working on a correct approach?

 $FileNamesList = @(Get-ChildItem C:\TestFiles\*.txt | Select-Object -ExpandProperty Name)
    
     for($i=0; $i -lt $FileNamesList.count; $i++)
        {      
            # original folder path
            $FilePath1 = 'C:\TestFiles\' + $FileNamesList[$i]
            
            #modified files after text is replaced will be copied in another folder
            $FilePath2 = 'C:\TestFilesModified\' + $FileNamesList[$i]   
    
            $OriginalFileData = Get-Content $FilePath1
    
        # Is this correct, can i assign foreach cmd result to a variable?
        $ModifiedFileData= ForEach($Row in $OriginalFileData ) 
                    {                 
                         If($Row.Split(",")[0] -eq "101") 
                         {
                            $Row -replace($Row.Split(",")[3]),"Test File"
                            $Row -replace($Row.Split(",")[5]),"Test Data"
                         } 

                     else{
                       $Row
                        }

             Out-File -FilePath $FilePath2 -InputObject $ModifiedFileData
            }

推荐答案

遗憾的是,这些文件没有标题,这将使它们成为正确的 Csv 文件并且使用起来更加可靠..

It's a shame those files don't have headers which would make them proper Csv files and so much more reliable to work with..

您现在可以做的是逐行循环遍历这些文件并在分隔符 , 处拆分.

What you can do now is to loop over these files line-by line and split on the delimiter character ,.

编辑

代码现在使用正则表达式来拆分逗号上的每个字符串,除非此逗号位于带引号的字段内.

The code now uses a regex to split each string on the comma, UNLESS this comma is inside a quoted field.

# create a regex string to split on the delimiter character ',' unless it isinside quotes
$commaUnlessQuoted = ',(?=(?:[^"]*"[^"]*")*[^"]*$)'
Get-ChildItem -Path 'D:\Test'-Filter '*.txt' -File | ForEach-Object {
    $file = $_.FullName
    $data = switch -Regex -File $file {
        '^101,' {
            # first field is '101', replace element index 3 with "Test File" and element index 5 with "Test Data"
            $fields = $_ -split $commaUnlessQuoted
            $fields[3] = "Test File"
            $fields[5] = "Test Data"
            # rejoin the fields with a comma
            $fields -join ','
        }
        '^002,' {
            # first field is '002', replace element index 3 with the current date
            $fields = $_ -split $commaUnlessQuoted
            $fields[3] = (Get-Date).ToLongDateString()
            $fields -join ','
        }
        # you can add as many regex conditions here as you like.
        # default means no conditions above matched, so return te line as-is
        default {$_}
    }
    $data | Set-Content -Path $file -Force
    # copy the modified file to somewhere else
    Copy-Item -Path $file -Destination 'C:\TestFilesModified'
}

$commaUnlessQuoted 的正则表达式详情:

,               Match the character "," literally
(?=             Assert that the regex below can be matched, starting at this position (positive lookahead)
   (?:          Match the regular expression below
      [^"]      Match any character that is NOT a """
         *      Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      "         Match the character """ literally
      [^"]      Match any character that is NOT a """
         *      Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      "         Match the character """ literally
   )*           Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   [^"]         Match any character that is NOT a """
      *         Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   $            Assert position at the end of the string (or before the line break at the end of the string, if any)
)

<小时>

根据您对这个问题的评论,如果您还需要抛出非终止异常,只需更改以下几行:


Per your comment on this question, if you need to also throw non-terminating exceptions, just change these lines:

$data | Set-Content -Path $file -Force
# copy the modified file to somewhere else
Copy-Item -Path $file -Destination 'C:\TestFilesModified'

进入

try {
    $data | Set-Content -Path $file -Force -ErrorAction Stop
    # copy the modified file to somewhere else
    Copy-Item -Path $file -Destination 'C:\TestFilesModified' -ErrorAction Stop
}
catch { throw }  # just rethrow the exception so it 'bubbles up' to the calling script

这篇关于如何在 Powershell 中一次替换多个 .txt 文件中的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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