简体   繁体   中英

Count characters for each line

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!}
}

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

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.

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 | %{} command | %{} where the iterative item is represented by $_ .

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