0

I have a text file which is comprised of only one line. I have had much trouble with splitting the file into a specific number of characters, then adding a string in front of each chunk of characters.

With a multi-line file, I can add characters to each line very easily using Get-Content -Path $path | foreach-object {$string + $_} | out-file $output but it is much more complicated with a file with only one line.

For example, if I had a file with these random characters, (******************************************) and i wanted to add a string to the start of every 10 chars, then it would look like this, (examplestring**********examplestring**********examplestring**********) and so on. I have researched everywhere but I have just managed to add the chars to the end of each chunk of characters.

Does anyone have a way of doing this? Preferably using streamreader and writer as get-content may not work for very large files. Thanks.

AJennings1
  • 159
  • 1
  • 2
  • 10
  • 1
    Hell @Adam, and welcome to StackOverflow. Don't feel too frustrated by an initial lack of answers, perhaps you can edit your question to make it clearer. For example, I'm unclear if there are line breaks in your file, or it's all just one big line. You may find it helpful to create indented code-blocks in your question using toolbar button that looks like `{}`, what you type in those blocks doesn't get word-wrapped. – Burt_Harris Sep 27 '16 at 00:00
  • yeah it was a little vague. Edited. – AJennings1 Sep 27 '16 at 00:13
  • 1
    Related question / answers: [How can I split a text file using PowerShell](http://stackoverflow.com/questions/1001776/how-can-i-split-a-text-file-using-powershell) – TessellatingHeckler Sep 27 '16 at 01:30
  • Isn't it actually an insertion prior to every 10 characters after the first character? And then prior to the last one? – Bill Bell Sep 28 '16 at 20:01

3 Answers3

1

Hmm, there are some dynamic parameters applicable to file-system get-content and set-content commands that are close to what you are asking for. For example, if test.txt contains a number of * characters, you might interleave every four * with two + characters with something like this:

get-content .\test.txt -Delimiter "****" | % { "++$_" } | Set-Content test2.txt -NoNewline

I don't know how close that is to a match for what you want, but it's probably useful to know that some of these provider-specific parameters, like '-Delimiter' aren't obvious. See https://technet.microsoft.com/en-us/library/hh847764.aspx under the heading 'splitting large files'.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Burt_Harris
  • 6,415
  • 2
  • 29
  • 64
0

With a manageable file size, you might want to try something like this:

$directory = "C:\\"
$inputFile = "test.txt"
$reader = new-object System.IO.StreamReader("{0}{1}" -f ($directory, $inputFile))
# prefix string of each line
$startString = "examplestring"
# how many chars to put on each line
$range = 10
$outputLine = ""

$line = $reader.ReadLine()
$i = 0
while ($i -lt $line.length) {
    $outputLine += $($startString + $line.Substring($i, [math]::min($range, ($line.length - $i))))
    $i += $range
}
$reader.Close()
write-output $outputLine

Basically it's using substring to cut out each chunk, prefixing the chumk with given string, and appending to the result variable.


Sample input:

==========================

Sample output:

examplestring==========examplestring==========examplestring======
J S
  • 1,068
  • 6
  • 7
0

Alternatively, here's a quick function that reads length-delimited strings from a file.

Set-StrictMode -Version latest

function read-characters( $path, [int]$charCount ) {
  begin {
    $buffer = [char[]]::new($charCount)
    $path = Join-Path $pwd $path
    [System.IO.StreamReader]$stream = [System.IO.File]::OpenText($path)
    try {
      while (!$stream.EndOfStream) {
        $len = $stream.ReadBlock($buffer,0,$charCount);
        if ($len) {Write-Output ([string]::new($buffer,0,$len))}
      } 
    } catch {
        Write-Error -Exception $error[0]  
    } finally {
        [void]$stream.Close()
    }
  }
}

read-characters .\test.txt -charCount 10 | 
    % {"+$_"} | 
    write-host -NoNewline

It could use some parameter checking, but should get you started...

Burt_Harris
  • 6,415
  • 2
  • 29
  • 64