4

I have a file containing special color encoding characters:

$ cat zz
aaa.gpg
bbb.gpg
ccc.gpg

$ cat -A zz
^[[38;5;216maaa.gpg^[[00m$
^[[38;5;216mbbb.gpg^[[00m$
^[[38;5;216mccc.gpg^[[00m$

I need to use sed command, to match the ending .gpg and remove it. So, if there were no special characters, I would use:

cat zz | sed 's/\.gpg$//'

So how can I match the .gpg^[[00m$ pattern with sed ?

I tried all possible permutations, but still does not work. For example:

cat zz | sed 's/\.gpg\^\[\[00m$//'
2
  • 1
    Remove them and then use sed? – muru Dec 24 '20 at 6:07
  • 1
    Do you actually want that file to contain the color encoding characters? – Ed Morton Dec 24 '20 at 19:05
2

What you see on the terminal as ^[ is the escape character. The second [ is a [.

You need to include the code for escape.

replace the ^[ with an escape character.

esc="$(echo '\033')"
sed 's/\.gpg'"${esc}"'\[00m$//'

or

esc='\x1b`
...
2
  • 3
    in sed we can use \x1b = esc – JJoao Dec 24 '20 at 10:54
  • 1
    @JJoao - thank you. sed 's/\.gpg\x1b\[00m$//' is the solution I like the best. – 400 the Cat Dec 25 '20 at 5:35
3
c=$(printf '\\(\33\\[[0-9;]*m\\)*')

Would store in $c a regexp that matches any number of graphic attribute setting sequences (colouring, bold, reverse video...), also known as sgr (set graphic rendition).

Then:

sed "s/${c}\.${c}g${c}p${c}g\(${c}\)\$/\5/"

Would remove a trailing .gpg including interspersed and preceding SGR sequences, but preserving trailing ones (like your \e[00m (sgr0) to restore default graphic rendition).

2
  • Is there some advantage in keeping the reset sequence? Say someone has a preference for a special colour (which he for example sets at the end of $PS1, then cat file1 | sed "..."; cat file2 the second file will be printed with undesired colour. – peterph Dec 24 '20 at 20:38
  • @peterph, it makes sense for that ^[[38;5;216maaa.gpg^[[00m for instance to be change to ^[[38;5;216maaa^[[00m instead of ^[[38;5;216maaa as the ^[[00m was intended to terminate the ^[[38;5;216m which we leave alone here. – Stéphane Chazelas Dec 24 '20 at 20:43
3

In order to remove ansi sequences (color and move) we can run something along the lines of

perl -pe 's/\e\[[0-9;]*[mGKHF]//g'

After that, things became much more clear...

1

First read a bit on ANSI escape sequences. SGR (Select Graphic Rendition - colours and similar) ends with the m character - so something like:

sed -r 's/^[\[[0-9;]*m//g'

should do the trick for well-behaved input. By well behaved I understand such, where the escape sequence is not interleaved by space characters (other than a space) - like \n or \r".

Note that ^[ is the escape character, not the characters ^ and [ themselves. As for entering the escape character itself, in the a console it is easiest by pressing Ctrl+V followed by Esc.

1

I'm assuming you want to leave the escape sequences in place, if they are already there. You can do this:

sed -E 's/\.gpg([[:cntrl:]]|$)/\1/' zz

This will match .gpg followed by either the end of the line or any control character (e.g. the ESC character.). If a control character is matched, it is preserved in the substitution with the \1.

If there are no escape sequences, then .gpg at the ends of lines will also be removed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.