0

I am new to WinPowerShell. Please, would you be so kind to give me some code or information, how to write a program which will do for all *.txt files in a folder next: 1.Count characters for each line in the file 2. If length of line exceeds 1024 characters to create a subfolder within that folder and to move file there (that how I will know which file has over 1024 char per line)

I've tried though VB and VBA (this is more familiar to me), but I want to learn some new cool stuff!

Many thanks!

Edit: I found some part of a code that is beginning

$fileDirectory = "E:\files";
foreach($file in Get-ChildItem $fileDirectory)
    {
       # Processing code goes here
    }

OR

$fileDirectory = "E:\files";
foreach($line in Get-ChildItem $fileDirectory)
{
 if($line.length -gt 1023){# mkdir and mv to subfolder!}
}
8
  • 1
    What have you got so far? If your intention is to learn, then just asking other people for the solution is counter-productive. Commented Oct 27, 2015 at 11:36
  • Why do you think is counter-productive? With stackoverflow, I've learn a lot when it comes to VBA for example. Please find my edit post. I know pretty much about OOP. I just need a code, to view, let me say, "a new way of thinking". Please support me. Thanks Commented Oct 27, 2015 at 11:41
  • 1
    You are asking for a couple of things but looks like you have shown no effort which is a precursor for asking questions? ... There that edit looks great as a start. What is your powerShell version Commented Oct 27, 2015 at 11:45
  • 1
    Here's a teachable moment. foreach ($file in gci *.txt) { gc $file | %{ if ($_.length -gt 1024) { move $file subdir; break } } } shows you two different notations for foreach. Can you spot the second one? Commented Oct 27, 2015 at 11:47
  • @Matt I think its version 3.0, I am using WIn7 built-in PS (cmd-> PowerShell) Commented Oct 27, 2015 at 12:03

3 Answers 3

2

If you are willing to learn, why not start here.

You can use the Get-Content command in PS to get some information of your files. http://blogs.technet.com/b/heyscriptingguy/archive/2013/07/06/powertip-counting-characters-with-powershell.aspx and Getting character count for each row in text doc

Sign up to request clarification or add additional context in comments.

1 Comment

Also, this TechNet blog entry is how I learned to understand if statements, which use comparison operators one doesn't often see in other languages.
1

With your second edit I did see some effort so I would like to help you.

$path = "D:\temp"
$lengthToNotExceed = 1024
$longFiles = Get-ChildItem -path  -File | 
    Where-Object {(Get-Content($_.Fullname) | Measure-Object -Maximum Length | Select-Object -ExpandProperty Maximum) -ge $lengthToNotExceed} 

$longFiles | ForEach-Object{
    $target = "$($_.Directory)\$lengthToNotExceed\"
    If(!(Test-Path $target)){New-Item $target -ItemType Directory -Force | Out-Null}

    Move-Item $_.FullName -Destination $target
}

You can make this a one-liner but it would be unnecessarily complicated. Use measure object on the array returned by Get-Content. The array being, more or less, a string array. In PowerShell strings have a length property which query.

That will return the maximum length line in the file. We use Where-Object to filter only those results with the length we desire.

Then for each file we attempt to move it to the sub directory that is in the same location as the file matched. If no sub folder exists we make it.


Caveats:

  1. You need at least 3.0 for the -File switch. In place of that you can update the Where-Object to have another clause: $_.PSIsContainer
  2. This would perform poorly on files with a large number of lines.

1 Comment

with command get-host, I discovered that I use 2.0 version. I will try this on win8, on my other comp. Thanks!
0

Here's my comment above indented and line broken in .ps1 script form.

$long = @()

foreach ($file in gci *.txt) {
    $f=0
    gc $file | %{
        if ($_.length -ge 1024) {
            if (-not($f)) {
                $f=1
                $long += $file
            }
        }
    }
}

$long | %{
    $dest = @($_.DirectoryName, '\test') -join ''
    [void](ni -type dir $dest -force)
    mv $_ -dest (@($dest, '\', $_.Name) -join '') -force
}

I was also mentioning labels and breaks there. Rather than $f=0 and if (-not($f)), you can break out of the inner loop with break like this:

$long = @()

foreach ($file in gci *.txt) {
    :inner foreach ($line in gc $file) {
        if ($line.length -ge 1024) {
            $long += $file
            break inner
        }
    }
}

$long | %{
    $dest = @($_.DirectoryName, '\test') -join ''
    [void](ni -type dir $dest -force)
    mv $_ -dest (@($dest, '\', $_.Name) -join '') -force
}

Did you happen to notice the two different ways of calling foreach? There's the verbose foreach command, and then there's command | %{} where the iterative item is represented by $_.

5 Comments

It worked! Just small question, if I had in several subdirectories for e.g: files/cchbc files/samsung files/etc, what line of a code do I need to change, to extract from all subs txt and put it accordinaly to its sub-subFolder Test? Thanks!
@Stefan0309 In the second example, change foreach ($file in gci *.txt) to foreach ($file in gci -filter *.txt -recurse). Also, change foreach ($line in gc $file) to foreach ($line in gc $file.FullName). I think the rest should be OK.
I have errors for files that hae >1024chars mv : Cannot find path 'D:\files\aleks\Sales and service business assistant.txt' because it does not exist. At line:4 char:5 + mv $_ -dest (@($dest, '\', $_.Name) -join '') -force + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (D:\files\aleks\...s assistant.txt:String) [Move-Item], ItemNotFoundExce ption + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
Ah. Maybe try doing mv $_.FullName etc. Sorry, I should've caught that.
mv $_.FullName (@($dest, '\', $_.Name) -join '') -force it works! Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.