简体   繁体   中英

Powershell read file for filename and path

I have the following script which runs on .zip files in a directory which have a whole directory structure with many files. These files then have 7zip run on them to extract them and then .eml is added to the extracted file.

& "c:\program files\7-zip\7z.exe" x c:\TestZip -r -oC:\TestRestore 2> c:\TestLog\ziplog.txt
& "c:\program files\7-zip\7z.exe" x c:\TestRestore -r -aos -oc:\TestExtract 2> c:\TestLog\sevenzip.txt
gci -path "c:\TestExtract" -file | rename-item -newname {$PSItem.name + ".eml"}

My problem is that out of these files sometimes the final extraction cannot be done by 7zip as it does not see it as an archive. I have found that these particular files if I just put .eml on them they are accessible as emails. So when the archive fails to extract I write the output to the sevenzip.txt file. What I need help with is how do I read this file to get the filenames and place them in a directory so I can add the .eml extension. An example of the output in the sevenzip.txt file is as follows

ERROR: c:\TestRestore\0\0\54\3925ccb78f80d28b7569b6759554d.0_4011
Can not open the file as archive


ERROR: c:\TestRestore\0\0\5b\6fa7acb219dec5d9e55d4eadd6eb1.0_3958
Can not open the file as archive

Any help would be greatly appreciated on how to do this.

Sorry for all the comments but I am working on this

$SourceFile = 'c:\testlog\sevenzip.txt'
$DestinationFile = 'c:\testlog\testlogextractnew.txt'
$Pattern = 'c:\\TestRestore\\' (Get-Content $SourceFile) | 
    % {if ($_ -match $Pattern){$_}} | 
    Set-Content $DestinationFile (Get-Content $DestinationFile).replace('ERROR: ', '') | 
    Set-Content $DestinationFile (Get-Content$DestinationFile).replace('7z.exe : ', '') | 
    Set-Content $DestinationFile

If there are no other errors, then you can pick those filenames out of the file with a regex pattern match:

$filesToFix = Select-String -Pattern "ERROR: (.*)" -LiteralPath 'c:\testlog\sevenzip.txt' | 
    ForEach-Object {$_.Matches.Groups[1].Value}

And probably rename them with

$filesToFix | ForEach-Object {

    Rename-Item -LiteralPath $_ -NewName {"$_.eml"}
}

If there might be other errors and you only want these, you'll need more work on the matching:

$fileContent = Get-Content -LiteralPath 'c:\testlog\sevenzip.txt' -Raw

$filesToFix = [regex]::Matches($fileContent, 
                 "ERROR: (.*)\nCan not open the file as archive",
                 'Multiline') | 
    ForEach-Object {$_.Groups[1].Value}

This is what I ended going with it is in the comments because I didn't know how to format but have worked it out now so hopefully this makes it easier to understand in case it is useful.

This section creates a list of all the files that failed to extract with their directory location. For use in next section.

$SourceFile = 'c:\\testlog\\sevenzip.txt' $DestinationFile = c:\\testlog\\testlogextractnew.txt' $Pattern = 'c:\\\\TestRestore\\\\' (Get-Content $SourceFile) | % {if ($_ -match $Pattern){$_}} | Set-Content $DestinationFile (Get-Content $DestinationFile).replace('ERROR: ', '') | Set-Content $DestinationFile (Get-Content $DestinationFile).replace('7z.exe : ', '') | Set-Content $DestinationFile

This is just some result checking

Get-Content C:\\testlog\\testlogextractnew.txt | Measure-Object –Line > c:\\testlog\\numberoffilesthatfailed.txt

This copies all files listed in the txt file to another directory

c:\\testlog\\testlogextractnew.txt | copy-item -destination "c:\\TestCopy"

This renames the current extensions to .eml

gci -path "C:\\TestCopy" -file | rename-item -newname { [io.path]::changeextension($_.name, "eml")}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM