PowerShell - 如何根据其他文件中的内容更新文件

时间:2018-02-06 18:49:51

标签: regex powershell

我已经在StackOverFlow搜索了所有内容,我似乎无法找到我需要帮助的解决方案。这是我的问题。

让我们说 File1.txt 我有以下内容(每行之间没有空格)

\\Serv02\LOC6\Client\726C30\032383\2200018023.pdf
\\Serv02\LOC6\Client\726C30\032383\2200718091.pdf
\\Serv02\LOC6\Client\726C30\030684\2300309040.pdf
\\Serv02\LOC6\Client\726C30\031274\2300429971.pdf

File2.txt 会有相同的信息,但是,我需要在每个1之前添加.pdf(在file2.txt内)< / p>

实施例: \\Serv02\LOC6\Client\726C30\032383\22000180231.pdf

我可以使用RegEx语句轻松更新file2.txt,但它只根据该RegEx语句更新内容。

File2.txt将包含比file1.txt更多的数据(更多信息的确切类型)。我只需要在1之前更新file2.txt,根据file1.txt中的内容添加.pdf

这是我正在使用的代码但是你可以看到它根本没有读取file1.txt,我只是使用RegEx语句来更新file2.txt,在.pdf之前添加1(代码下面的工作是在.pdf之前添加1,但我没有迭代通过file1.txt)

clear-host
set-location c:\temp

$File = "C:\Temp\file1.txt"
$FileZ = "C:\Temp\file2.txt"
$File2 = (Get-ChildItem $fileZ) | Select -ExpandProperty BaseName
$regex01 = '(\\Serv02\LOC6\Client\726C30\\d{1,6}\\d{1,10})(.pdf)$'
get-content $fileZ | % { $_ -replace $regex01, '${1}1${2}' -join "`r`n" } | out-file -Encoding default "c:\Temp\$File2.txt"
start-sleep -Seconds 2
$NewMRC = Get-ChildItem "$file2.txt" | Select -ExpandProperty Name 
Get-ChildItem $NewMRC | rename-item -NewName {$_.Name -replace ".txt",".MRC2"} 

如果file1.txt有另一行与RegEx不匹配,如上所示,则不会使用该行更新file2.txt

\\Serv03\LOC7\Client\780D30\031456\8675309123.pdf

我希望我已经解释得这么好了。我不是PowerShell的新手,但我远非专家。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

执行此操作的一种方法:将第一个文件的文件内容检索到数组中,然后检索第二个文件的内容。对于第二个文件中的每一行:如果第一个文件的内容有一行与当前行匹配,则输出修改后的行;否则,只输出当前行。

$pattern = '(\\{2}(?:[^\\]+\\)+)([^\\\.]+)(\.pdf)'
$file1Content = Get-Content "file1.txt"
Get-Content "file2.txt" | ForEach-Object {
  if ( $file1Content -contains $_ ) {
    $_ | Select-String $pattern | ForEach-Object {
      "{0}{1}1{2}" -f
        $_.Matches[0].Groups[1].Value,
        $_.Matches[0].Groups[2].Value,
        $_.Matches[0].Groups[3].Value
    }
  }
  else {
    $_
  }
}

第一个匹配组($_.Matches[0].Groups[1].Value)是\\servername\sharename\path,第二个匹配组是没有扩展名的文件名,第三个匹配组是文件扩展名。

答案 1 :(得分:0)

我修改了你的代码如下。该方法读取File1.txt的内容并将其存储在变量中。然后在File2.txt的每一行上迭代以检查正则表达式以及该行是否存在于file1内容中。如果是,那么用你想要的任何东西替换它。在追加模式下将其输出到.tmp文件。处理File2.txt中的所有行后,将其替换为.tmp文件。

clear-host
set-location c:\temp

$File = "file1.txt"
$FileZ = "file2.txt"

# PS2
$File1 = get-content $File | Out-String
# PS3
# $File1 = get-content $File -Raw

$File2 = (Get-ChildItem $fileZ) | Select -ExpandProperty BaseName

if( test-path "$File2.tmp" ) { remove-item "$File2.tmp" }

$regex01 = '(\\\\Serv02\\LOC6\\Client\\726C30\\\d{1,6}\\\d{1,10})(.pdf)$'
get-content $fileZ |% { 
    $line = $_
    $find = $line -replace '\\','\\'
    if ( ($line -match $regex01) -AND ( $File1 -match $find ) ) {
        $line -replace $regex01,'${1}1${2}' -join "`r`n" 
    } else {
        $line
    }
} | out-file "$File2.tmp" -append

remove-item "$File2.txt"
rename-item "$File2.tmp" "$File2.txt"

#start-sleep -Seconds 2
#$NewMRC = Get-ChildItem "$file2.txt" | Select -ExpandProperty Name
#Get-ChildItem $NewMRC | rename-item -NewName {$_.Name -replace ".txt",".MRC2"} 

注意:

  • 您的代码的最后3行似乎与您的问题陈述无关。所以我对这些内容进行了评论。
  • $find = $line -replace '\\','\\':我们正在使用双反斜杠\替换单反斜杠\\。但是在-replace的第一个参数中,它必须被转义,而在第二个参数中它必须不是。因此,即使它们看起来相同,它们也会有不同的解释。