6

I have text files that include the ANSI movement codes ESC[xC and ESC[xD. I want to filter these out but with each line output with those codes taken into account.

Consider the line:

this cat is greenESC[12DdogESC[4Cwhite 

I would like this piped out as

this dog is white 

Above ESC means the escape code \0x1b (or \033).

2

2 Answers 2

1

I'm sure there's a better way (and I'm sure there's better Perl), but this seems to do the trick:

perl -M5';$e="\x1b";' -lne 'chomp;if(/$e\[\d+[CD]/){$ns="";$p=0;while(/$e\[(\d+)([CD])/g){if(!$ns){$ns=$`;$p=length($ns)}$p+=($2eq"C"?+$1:-$1);($a=$'"'"')=~s/(^[^$e]+).*/$1/;if($a=~/^[^$e]/){substr($ns,$p,length($a),$a);$p+=length($a)}}print $ns}else{print $_}' 
2
  • -l chomps already Commented Oct 25, 2023 at 6:33
  • perl supports \e for ESC (inside "...", qq(...), /.../). Commented Oct 25, 2023 at 6:35
1

Using ANSI-C quoting (bash)

$ string=$'this cat is green\e[12Ddog\e[4Cwhite' $ echo "$string" this dog is white 

Explanation: the $'...' syntax is ANSI-C Quoting, which expands the escape sequences in the string (you can also use \033—I just like \e better). This works in cases where the text stored in a variable already has the escape sequences interpreted.

Using shell parameter expansion (bash)

$ string='this cat is green\e[12Ddog\e[4Cwhite' $ echo "${string@E}" this dog is white 

Explanation: the ${variable@E} syntax expands the backslash escape sequence in variable.

With older versions of bash

These first two methods work for me in bash 5.2.26, but if you have an older version, you may have to do it with printf:

$ string='this cat is green\033[12Ddog\033[4Cwhite' $ printf "%b\n" "$string" this dog is white 

Explanation: "%b" enables backslash interpretation for printf.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.