none
Powershell replace characters in text file RRS feed

  • Question

  • I copy files from one PC to another for backup, then I run a DIR command for each PC (folder) and after some trimming of high level directory info I run FC to identify differences. The problem is sometimes the time stamps (minutes) don't match so I get differences.

    I am very new to Powershell and can't figure out why the follow commands does nothing.

    Get-Content "G60_TESTMusic.txt") |
     Foreach-Object {$_ -replace ":??", " "} |
     Set-Content "G60_TESTMusic.txt"

    The following is a sample of the text file.

     Directory of \xMusic
    11/27/2002  11:01 AM         8,443,130 Cara.wav
    08/15/2007  08:53 PM           147,968 Covers.doc
    11/25/2008  07:15 PM            77,721 old skool play list.wpl
    04/16/2006  10:27 AM               516 Request.txt
    12/28/2005  12:40 PM         5,361,792 scent.mp3

    Friday, December 30, 2016 1:16 AM

Answers

  • If you would use PowerShell commands instead of trying to use batch commands from PowerShell your issues would all go away.  With PS commands you can just ignore the file times or compare them as times.  YOU cannot compare text times in any way.  Text will not compare correctly.  Trying to fudge the text just creates new issues.

    You can compare to file like this:

    $file1.Length -ne $file2.Length

    or

    $file1.LastWriteTime -gt $file2.LastWriteTime


    \_(ツ)_/


    • Edited by jrv Saturday, December 31, 2016 1:57 AM
    • Proposed as answer by BOfH-666 Monday, January 2, 2017 12:05 AM
    • Marked as answer by Richard MuellerMVP, Moderator Wednesday, January 18, 2017 5:26 PM
    Saturday, December 31, 2016 1:55 AM

All replies

  • If the copy is successful (no errors) you can be sure all files were copied. There is no need to verify this.

    A copy will always have a different timestamp.

    You can easily list on file names like this:

    Get-ChildItem C:\mymusic | select fullname


    \_(ツ)_/

    Friday, December 30, 2016 2:01 AM
  • jrv is right - and if you use robocopy par example with the option to write a log file you already have your file list.

    But to answer your question: The -replace operator works with regular expressions and there the "?" has another meaning than using it as a wildcard when you search for files with windows explorer. To make your code work you have to deliver a proper regular expression to match a colon followed by two digits:

    Get-Content "G60_TESTMusic.txt") | 
     Foreach-Object {$_ -replace ":\d{2}", " "} | 
     Set-Content "G60_TESTMusic.txt"


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Edited by BOfH-666 Friday, December 30, 2016 5:58 AM
    Friday, December 30, 2016 3:41 AM
  • Tried the ":\d{2}" and source file was not changed. Got same result as ":??".
    I tried to find out if the colon is a special character but was not successful. Will have to keep searching.
    Thanks.
    BTW jrv my backup process does not always occur right after I add a file to my base system, due to other factors. Also the FC lets me know what I forgot to backup or files removed from my base that I no longer want in the backup. Not the best system, but it is a work around for my environment.  Thanks.

    Saturday, December 31, 2016 1:37 AM
  • So you changed something else in your code. If you try this: (exactly as it is here)
    '08/15/2007  08:53 PM  147,968 Covers.doc' -replace ':\d{2}', 'xXX'
    you should get this:
    08/15/2007  08xXX PM  147,968 Covers.doc
    So the colon followed by 2 digits is replaced by "xXX".

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Edited by BOfH-666 Saturday, December 31, 2016 1:54 AM
    Saturday, December 31, 2016 1:53 AM
  • If you would use PowerShell commands instead of trying to use batch commands from PowerShell your issues would all go away.  With PS commands you can just ignore the file times or compare them as times.  YOU cannot compare text times in any way.  Text will not compare correctly.  Trying to fudge the text just creates new issues.

    You can compare to file like this:

    $file1.Length -ne $file2.Length

    or

    $file1.LastWriteTime -gt $file2.LastWriteTime


    \_(ツ)_/


    • Edited by jrv Saturday, December 31, 2016 1:57 AM
    • Proposed as answer by BOfH-666 Monday, January 2, 2017 12:05 AM
    • Marked as answer by Richard MuellerMVP, Moderator Wednesday, January 18, 2017 5:26 PM
    Saturday, December 31, 2016 1:55 AM
  • The only change I made was your suggestion.
    Your second suggestion did not work either.

    However this did work.    Thanks for your effort.
    (Get-Content "G60_TESTMusic.txt") | 
     Foreach-Object {$_ -replace ":[0-9][0-9]","xXX"} |
     Set-Content "G60_TESTMusic.txt"

    Sunday, January 1, 2017 11:29 PM
  • Your second suggestion did not work either.

    "Second suggestion"? What second suggestion?

    You really should learn the basics of Powershell. Some good starting points you can find here:  Beginner Sites And Tutorials


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Monday, January 2, 2017 12:05 AM
  • Re: "Second suggestion"? What second suggestion?
    If I read this listing/page correctly, once you used double quotes (12/30) and once single quotes (12/31) in your suggestions. 

    Anyway, thanks for your effort.

    Saturday, January 7, 2017 11:12 PM
  • Ah ... OK ... now I know what you mean. In this case that difference does not matter. I try to pay attention but sometimes I miss it. 

    Strings in single quotes will not be evaluated. Strings in double quotes will. Usually I try to think about to use single quotes when there's nothing to evaluate.


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Sunday, January 8, 2017 1:11 AM