Preencha a última linha com nada além de vazio para uma posição específica

4

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)

Informação

No Windows 10 , o SED abaixo é usado para reformatar um arquivo para que > CRLF está na posição de linha 80 de cada linha até o EOF e atualiza o arquivo no local, mas a última linha nunca tem um CR ou LF .

O arquivo original é uma enorme cadeia de caracteres imprimíveis sem retornos de linha ou feeds de linha nesse arquivo, então tudo começa na linha número um e abaixo é o SED Eu uso para reformatá-lo.

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

Meu problema

Não consigo descobrir como fazer com que a última linha desse arquivo seja preenchida até a posição 80 com espaço em branco e não tenha retorno de carro.

Eu tentei algumas coisas, mas estou longe e prefiro não listar todas as coisas que tentei, então mostrei a sintaxe do sed que eu corri acima para essa parte. Tenho certeza de que há algo simples que estou negligenciando, mas. . .

Preferência

Eu preferiria usar o SED para isso e tenho que manter o CRLF nas outras linhas acima da última linha neste mesmo formato, mas estou disposto a olhar para outras soluções do Windows também, se não for muito complexo.

Considerações

Os caracteres da última linha podem ter 1 caractere, 79 caracteres, talvez até mesmo 80 caracteres. Nesse ponto, eu preciso garantir que não haja retorno de carro ou alimentação de linha na última linha se o espaço não branco preencher para alinhar a posição 80 na última linha.

Enquanto a captura de tela contém 91 linhas, esses arquivos podem conter mais linhas ou menos linhas, mas as regras sempre precisam ser as mesmas; alimentação de linha de retorno de carro na posição 80 em cada linha e a última linha precisa ter exatamente 80 posições para preencher com espaço em branco, se necessário, e nenhum retorno de carro ou avanço de linha, independentemente disso.

Formato dos dados do ponto de partida

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

Formato de dados final desejado

Eu não consigo descobrir como preencher a última linha no arquivo com espaço vazio sem CR ou LF no final para a posição 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--->

Aviso: Se você usar os dados acima para testar, substitua os caracteres literais de [CR][LF] pelo que eles realmente deveriam representar .

    
por Pimp Juice IT 29.09.2016 / 04:56

1 resposta

6

Tente isto:

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

(eu quebrei o comando em várias linhas apenas por legibilidade na apresentação; você pode fazer tudo em uma linha.) O s/$/###…###/ acrescenta 80% dos caracteres#, e, em seguida, o s/\(\r\n.\{80\}\)#*$// procura essa sequência:

  • \r\n
  • 80 de qualquer caractere
  • qualquer número de # s
  • até o final do buffer

e o substitui pelo grupo formado pelas duas primeiras balas. Em outras palavras, mantém os caracteres n que são a última linha do arquivo e os 80- n # caracteres que o seguem, e descarta os caracteres n # que os seguem.

Depois de verificar se isso funciona, basta alterar todas as ocorrências de # no comando acima para espaços.

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*$//" "%File%"
GOTO :EOF

Podemos tornar isso um pouco mais fácil de ler e menos tedioso para digitar.

  1. Pure sed

    Se o seu texto é todo alfanumérico, e há algum caractere (como @ ) que nunca aparecerá nos seus dados então você pode fazer algo assim:

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

    Se você quiser tornar seu script legível, ao custo de torná-lo um pouco mais detalhado, dê um passo adiante:

      -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.
    

    Se não houver um caractere único que nunca apareça nos seus dados, mas há alguns (curtos) caracteres seqüência , como () , que nunca aparece, você pode usar o mesmo princípio:

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

    Tenha cuidado ao lidar com personagens que são especiais em expressões regulares; por exemplo, . , * , [ , ^ , & etc. (E não inclua os # -comments no seu script nesses locais; para quebrar um comando simples em várias linhas, o \ deve ser o último caractere na linha (antes da nova linha) e não em um comentário.)

  2. Usando o shell

    Mesmo princípio:

    #!/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*$//' "C:\Folder\test.txt"
    
por 29.09.2016 / 07:14