5

I have a .pem file that after some formatting it shows like this:

-----BEGIN
RSA
PRIVATE
KEY-----
MIIEogIBAAKCAQEAoK3D4mMIRnzPaYqHidgpBnDDzLlcYYd0GoB0pQGyGSHDW7KO3K+VeJP90GhE
ZTEWJLp2N5DR/KT+5Vg7cgdx/GCCrnlbW0McP/IvkYAuWCgbzoXH9eE+kDRtAmurBYCk7OTOwQ26
..........................LONG LONG LONG KEY................................
QRRLFsXua9spUh0yPd163IZStKZMhZBPJfMaqbi1WF+j21DdYyS0qpaZQRjFzRLvGuXeGLZG/COD
ip10XRJMMXY0m14bqOTcqKTya/5PTJIjDWC22+soIjLy0ZjWKo9n05Oal2t4q35kbos=
-----END
RSA
PRIVATE
KEY-----

And I obviously need to be like:

-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAoK3D4mMIRnzPaYqHidgpBnDDzLlcYYd0GoB0pQGyGSHDW7KO3K+VeJP90GhE
ZTEWJLp2N5DR/KT+5Vg7cgdx/GCCrnlbW0McP/IvkYAuWCgbzoXH9eE+kDRtAmurBYCk7OTOwQ26
..........................LONG LONG LONG KEY................................
QRRLFsXua9spUh0yPd163IZStKZMhZBPJfMaqbi1WF+j21DdYyS0qpaZQRjFzRLvGuXeGLZG/COD
ip10XRJMMXY0m14bqOTcqKTya/5PTJIjDWC22+soIjLy0ZjWKo9n05Oal2t4q35kbos=
-----END RSA PRIVATE KEY-----

How can I do it using awk or sed?

All the tutorials that I've found online shows how to do it for the whole text or for one type of pattern like aaaabbbaaacccc which I found confusing.

I tried something like this:

tr ' ' '\n' < test.pem  | awk '/BEGIN\nRSA\nPRIVATE\n$/ { printf("%s\t", $0); next } 1' > test-format.pem

But that failed.

I don't know if it matters or not, but I'm doing this in a shell #!/bin/sh script in a python:3.5-alpine docker container.

Any help is greatly appreciated.

cuonglm
  • 153,898
Fadi
  • 315
  • 1
  • 3
  • 13

4 Answers4

12

One way with sed:

sed -e '/^---/ {
  :1
  $!N
  s/\n/ /
  /---$/!b1
}' <file

This approach does the job straight way:

  • If line start with ---, then enter the code block
  • Inside code block, we create a loop label named 1
  • We read Next line of the input if current line is not the last line $
  • Replace newline \n with a space
  • If next line does end with ---, break ! the loop, otherwise restart the loop b1
cuonglm
  • 153,898
3

Suppose the key lines should be collected in one long line too:

sed '
    :a
    N
    /\n-\|-\n/{
        P
        D
    }
    s/\n/ /
    ta
    ' file
Costas
  • 14,916
3

Here's another sed:

sed '/^---/,/---$/{H;/^---/h;/---$/!d;x;s/\n/ /g;}' infile

this one uses a range and the hold buffer. It appends each line in that range to the hold buffer, overwriting it if it's the start of range; it deletes the line if it's not the end of range else it exchanges buffers and replaces all newlines with spaces.
And a different approach with ed:

ed -s infile <<\IN
?^---?,.-s/$/ /
?^---?,$j
1,/---$/-s/$/ /
1,/---$/j
w
q
IN

This one uses four ranges: first it searches backwards (ed starts at end of file) and it appends a space to end of each line in the first range and then joins the lines in the second range (which are actually lines in the first one plus one more line); it then does the same but starting from the beginning of the file.

don_crissti
  • 82,805
2

Doing the posix version as requested in the comment:

#!/bin/sh
jump=1

while IFS= read -r lin; do

  case $lin in 
    ----*)
        jump=0
    ;;
    *----)
        jump=1
    ;;
  esac

  if [ "$jump" = "1" ]; then 
        printf '%s\n' "$lin" 
  else
        printf '%s' "$lin "
  fi

done <"$1"

To call it:

./script file.txt >thedest.txt 
cuonglm
  • 153,898