Fill the last line up with nothing but emptiness to a specific position

batch filecommand linesed

I need to fill a file's last line with empty white space until position 80, and I also need to ensure it always ends with no new
lines (CR/LF)

Information

On Windows 10 the below SED is used to reformat a file so that CRLF is at line position 80 of every line until the EOF and update the file in-place but the last line never has a CR or LF.

The original file is a huge string of printable characters with no carriage returns or line feeds in this file so everything starts out on line number one and below is the SED I use to reformat it.

sed -i -e "s/.\{80\}/&\r\n/g" "C:\Folder\test.txt"

My Trouble

I cannot figure out how to make the very last line of this file be filled in the rest of the way until position 80 with white space and have no carriage return.

I've tried a few things but I'm way off and would prefer to not list all the things I have tried so I showed the sed syntax I run above for that part. I'm sure there is something simple I'm overlooking but. . .


Preference

I would prefer to use SED for this and I have to keep the CRLF in the other lines above the last line in this same format but I'm willing to look at other Windows solutions too if not too complex.


Considerations

The last line characters could be 1 character, 79 characters, to maybe even potentially 80 characters at which point I'd need to ensure there is no carriage return or line feed on the last line if non-white space does fill it to line position 80 on the last line.

While the screen shot contains 91 lines, these files could contain more lines or less lines but the rules always need to be the same; carriage return line feed at position 80 on each line and the last line needs to be exactly 80 positions over filling in with white space if needed and no carriage return or line feed on it regardless.


Starting Point Data Format

Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~EOL any legnth and no CR or LF

Desired Ending Data Format

I can't figure out how to fill the last line in the file with empty space with no CR or LF at the end of it to line position 80.

Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
Data*~123 dummydata Data*~123 dummydata Data*~123 dummydata Data**endoflinedata~[CR][LF]
EOL any legnth less than 80 no CR or LF fill rest empty space to position 80--->

Warning: If you use the above data to test with, please be sure to replace the literal characters of [CR][LF] with what those are really supposed to represent.

Best Answer

Try this:

sed -i -e 's/.\{80\}/&\r\n/g' \
  -e 's/$/################################################################################/' \
  -e 's/\(\r\n.\{80\}\)#*$/\1/' "C:\Folder\test.txt"

(I have broken the command into multiple lines just for readability in presentation; you can do it all on one line.)  The s/$/###…###/ appends 80 # characters, and then the s/\(\r\n.\{80\}\)#*$/\1/ looks for this sequence:

  • \r\n
  • 80 of any character
  • any number of #s
  • up to the end of the buffer

and replaces it with the group formed by the first two bullets.  In other words, it keeps the n characters that are the last line of the file and the 80-n # characters that follow it, and discards the n # characters that follow those.

Once you've verified that this works, just change all occurrences of # in the above command to spaces.


OP's Final Working Solution

NOTE: The SET s10= line has 10 empty spaces in it to the right of the equal sign.

Batch Script

@ECHO ON

SET File=C:\Folder\test.txt
::: The below s10 variable equals ten white\empty spaces - so it has 10 blank spaces in it
SET s10=          
SET s40=%s10%%s10%%s10%%s10%
SET s80=%s40%%s40%

sed -i -e "s/.\{80\}/&\r\n/g" -e "s/$/%s80%/" -e "s/\(\r\n.\{80\}\)\s*$/\1/" "%File%"
GOTO :EOF

We can make this a little easier to read and less tedious to type.

  1. Pure sed

    If your text is all alphanumeric, and there is some character (such as @) that will never ever appear in your data, then you can do something like this:

      -e 's/$/@@@@@@@@@@/' \        # Append 10 @ characters to the line.
      -e 's/@/        /g' \         # Change each @ to eight spaces.
    

    If you want to make your script unambiguously readable, at the cost of making it somewhat more verbose, take it one step further:

      -e 's/$/@@@@@@@@@@/' \        # Append 10 @ characters to the line.
      -e 's/@/@@@@@@@@/g' \         # Change each @ to eight @s (there are now 80 @s).
      -e 's/@/ /g'        \         # Change each of the 80 @s to a space.
    

    If there's no single character that never appears in your data, but there is some (short) character sequence, like (), that never appears, you can use the same principle:

      -e 's/$/()()()()()()()()()()/' \  # Append 10 () pairs to the line.
      -e 's/()/        /g' \            # Change each () to eight spaces.
    

    Be careful when dealing with characters that are special in regular expressions; e.g., ., *, [, ^, &, etc.  (And don't include the #-comments in your script in those places; to break a simple command across multiple lines, the \ must be the last character on the line (before the newline) and not in a comment.)

  2. Using the shell

    Same principle:

    #!/bin/sh
          ︙
    s="          "                  # Set $s to 10 spaces.
    s80="$s$s$s$s$s$s$s$s"          # Set $s80 to 8 copies of $s; i.e., 80 spaces.
          ︙
    sed -i -e 's/.\{80\}/&\r\n/g' \
      -e 's/$/'"$s80"'/' \
      -e 's/\(\r\n.\{80\}\)\s*$/\1/' "C:\Folder\test.txt"
    
Related Question