header
header Register : : Login header
header
divider
menuleft
menuright
submenu
left

[August 25th, 2008] Check the home page regarding PowerShell related news from a brand new sponsor: Idera

Files updated, but can't write back
Last Post 05 Jul 2008 04:38 AM by halr9000. 13 Replies.
Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
01 Jul 2008 04:59 PM  

$updtFileName = " "
$myFiles = Select-String "kct" *.sql -list | % {$_.get_filename()}
$myFilesNocount = select-string [^"nocount"] -path $myFiles -list | % {$_.filename}
$myFilesNocount | % { get-content $_} | join-string -newline | %{$_ -replace "\*\*\*\*/", "****/`nset NOCOUNT ON"}

Can't get this to work | out-file $updtFileName
I've got 300 files that I need to update. This works fine as long as I want 1 output file with all the output from 300 files. I need to make another round of updates to existing sql files, add 1 line to those I modified and didn't already add this to. Input is an array of strings and when I try to preface the filename (string) from $myFilesNoCount I get the message that Powershell "could not find a part of the path" and displays the current directory. I've tried both set-content and out-file with equal success. All the examples and books I've gone through are very good at c:\testfile.txt | .....| out-file c:\testfile.txt. How can I pipe 300 files through to come out with 300 identifiable files? I'd hope to prepend a simple string showing which files I'd modified, but sooner or later (after testing) they need to go back to the original name.
glnsizeUser is Online
Basic Member
Basic Member
Posts:101

--
01 Jul 2008 08:59 PM  

without rewriting your code... try.


$myFiles = Select-String "kct" *.sql -list | % {$_.get_filename()}
$myFilesNocount = select-string [^"nocount"] -path $myFiles -list | % {$_.path}
$myFilesNocount | % {
$updateFileName = $_ + ".new"
get-content $_ | join-string -newline | %{
$_ -replace "\*\*\*\*/", "****/`nset NOCOUNT ON"
}| out-file $updateFileName -encoding ASCII
}

-Glenn

kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
02 Jul 2008 01:39 PM  

This is what I had come up with after deciding to forgo interactive development, write some things down on the napkin, and then open an editor.  That was after I'd converted all 300 files and then written the same 1500 lines to 300 new files.


$myFiles = Select-String "kct" dbo.*.sql -list | % {$_.get_filename()}
$myFilesNocount = select-string [^"nocount"] -path $myFiles -list | % {$_.filename}
#
foreach ($FileName in $myFilesNoCount) 
{
    $updtFileName = "kct$FileName"
    get-content $FileName | join-string -newline | 
    % {$_ -replace "\*\*\*\*\*\*\*\*/", "********/`nset NOCOUNT ON"} | 
    out-file $updtFileName
}

I am still unhappy with writers, more likely publishers, who keep putting out technical texts where all the examples use one variable, one file, and few examples of commands strung together to do something useful. I've been told the producer/publisher outlook is beginning text/video because there is no market for advanced/experienced technical information. And that leads to another post. Thanks again.

halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
02 Jul 2008 02:23 PM  
Here's a variation on the theme:

$SQLpath = "\\server\share\path"
Get-ChildItem -Path $SQLPath -Filter dbo.*.sql | ForEach-Object {
    if ( ( Select-String -Path $_ -Pattern "kct" ) -and
        ( Select-String -Path $_ -Path [^"nocount"] ) ) {
        $NewFileName = "kct{0}" -f ( $_.Name )
        get-content $_ | join-string -newline | ForEach-Object {
            $_ -replace "\*\*\*\*\*\*\*\*/", "********/`nset NOCOUNT ON"
        } | out-file $NewFileName -Encoding ascii
    }
}
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
02 Jul 2008 02:27 PM  
And if it works, take out the $Newfilename line, and replace the "out-file $newfilename -encoding ascii" part with "Set-Content -encoding ascii" and that will replace them inline. You can even toss a "-whatif" to the end of the set-content line if you want to run it through once.
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
02 Jul 2008 10:20 PM  

Changing the extra path statement to pattern got it to work. 

Confirm and whatif seem to work with set-content, but not with out-file

"anything" | out-file  dog.txt -encoding ascii -whatif   --  Wrote text to file with no prompt.

set-content  dog.txt "anything" -whatif  -- Does generate the whatif:.... and does not actually write to file.

Thanks for throwing in the format operator.  Not only did it take a while to stumble on the reference, but I don't understand the way this works.  I can see the benefit of formatting numerals, percentages, and time, but I'm not sure why kct{0} is a good thing.

kct

halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
03 Jul 2008 03:46 AM  
I threw you a curve ball there with the -f. :) You are right, there's no special advantage to it here. You can always do this sub-expression $() :
$NewFileName = "kct$( $_.Name )"
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
03 Jul 2008 02:24 PM  

I could hit a curve, it was the fastball that kept me on the bench, and maybe poor fielding.

Thanks for this one

if ( ( Select-String -Path $_ -Pattern "kct" ) -and
        ( Select-String -Path $_ -Path [^"nocount"] ) ) {
I hated going through the file twice and now I have an example with two variables to work from.

 

 

halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
03 Jul 2008 02:50 PM  
Technically, you're still going through the file twice. With some clever regular expressions that could perhaps be cut down to one though. Or...you could change the loop to iterate over each line of every file, e.g. ls | get-content | ? { $_ -match "kct" } | # do more stuff here
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
03 Jul 2008 03:24 PM  

To many years of debates over whether count > 0 or exists or ...  is more efficient.  I saw the "and" and then ignored the two select-string statements. 

My original pass through used piping from Regex to Regex changing char to nchar and varchar to nvarchar using $_. and should have added the nocount line.  Probably most efficient way, at least when you have multiple tests or multiple changes.

The processing still went a lot faster than any manual changes on my part.

halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
03 Jul 2008 03:44 PM  
There are exceptions, but I'm a big believer in clarity over raw efficiency.
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
04 Jul 2008 11:53 PM  
Posted By halr9000 on 07/03/2008 7:44 AM
There are exceptions, but I'm a big believer in clarity over raw efficiency.



Well I'd answer the same way based on age and experience.  I started putting a lot more comments in code when I kept gettng questions prefaced with "you know that program you wrote two years ago..."  I'll try to write something as efficient as possible and yet long ago realized that making the process understandable was usually more critical.

I'm still trying to learn Powershell so finding out what chews up cycles for no good reason is something to ask for feedback on. 

Have a happy fourth.

bsonposhUser is Offline
Basic Member
Basic Member
Posts:393
Avatar

--
05 Jul 2008 02:31 AM  
I would foreach the file names with switch. Elegant, efficient and readable.

foreach($file in $files)
{
   switch -regex -file $file
   {
      $regex1   {'Do something'}
      $regex2   {'Do something else'}
      default     {'default action'}
   }
}
Brandon Shell
----------------
Microsoft Powershell MVP
https://mvp.support.microsoft.com/profile/Brandon
Blog: http://www.bsonposh.com
halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
05 Jul 2008 04:38 AM  
P.S. Switch rocks.

And @kct, BSonPosh here is your man when you want to talk efficiency. Check out his blog posts on ADSI benchmarks.
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
You are not authorized to post a reply.

Active Forums 4.1
right
   
footer Sponsored by Quest Software • SAPIEN Technologies • ShellTools, LLC • Microsoft Windows Server 2008 footer
footer