15

I have some variable $a. This variable have non printing characters (carriage return ^M).

>echo $a
some words for compgen
>a+="END"
>echo $a
ENDe words for compgen

How I can remove that char? I know that echo "$a" display it correct. But it's not a solution in my case.

Stepan Loginov
  • 1,667
  • 4
  • 22
  • 49

5 Answers5

33

You could use tr:

tr -dc '[[:print:]]' <<< "$var"

would remove non-printable character from $var.

$ foo=$'abc\rdef'
$ echo "$foo"
def
$ tr -dc '[[:print:]]' <<< "$foo"
abcdef
$ foo=$(tr -dc '[[:print:]]' <<< "$foo")
$ echo "$foo"
abcdef
devnull
  • 118,548
  • 33
  • 236
  • 227
  • 10
    *Beware:* This will also remove umlauts and many other actually printable characters. – Chiru Oct 15 '14 at 07:05
  • 5
    With this tweak from https://alvinalexander.com/blog/post/linux-unix/how-remove-non-printable-ascii-characters-file-unix I got better results: `tr -cd '\11\12\15\40-\176'` – qneill Dec 28 '17 at 20:31
  • @Chiru, ...that varies depending on your operating system and your current locale. With `LC_CTYPE` set to a character set where umlauts are valid, and an OS providing multibyte-aware tools, they'll survive. – Charles Duffy Feb 19 '22 at 17:54
11

To remove just the trailing carriage return from a, use

a=${a%$'\r'}
chepner
  • 497,756
  • 71
  • 530
  • 681
4

I was trying to send a notification via libnotify, with content that may contain unprintable characters. The existing solutions did not quite work for me (using a whitelist of characters using tr works, but strips any multi-byte characters).

Here is what worked, while passing the test:

message=$(iconv --from-code=UTF-8 -c <<< "$message")
We Are All Monica
  • 13,000
  • 8
  • 46
  • 72
2

As an equivalent to the tr approach using only shell builtins:

cleanVar=${var//[![:print:]]/}

...substituting :print: with the character class you want to keep, if appropriate.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
0
tr -dc '[[:alpha:]]'

will translate your string to only have alpha characters (if that is needed)

rubo77
  • 19,527
  • 31
  • 134
  • 226