简体   繁体   中英

Escaping special characters with sed

I have a script to generate char arrays from strings:

#!/bin/bash
while [ -n "$1" ]
do
    echo -n "{" && echo -n "$1" | sed -r "s/((\\\\x[0-9a-fA-F]+)|(\\\\[0-7]{1,3})|(\\\\?.))/'\1',/g" && echo "0}"
    shift
done

It works great as is:

$ wchar 'test\n' 'test\\n' 'test\123' 'test\1234' 'test\x12345'
{'t','e','s','t','\n',0}
{'t','e','s','t','\\','n',0}
{'t','e','s','t','\123',0}
{'t','e','s','t','\123','4',0}
{'t','e','s','t','\x12345',0}

But because sed considers each new line to be a brand new thing it doesn't handle actual newlines:

$ wchar 'test
> test'
{'t','e','s','t',
't','e','s','t',0}

How can I replace special characters (Tabs, newlines etc) with their escaped versions so that the output would be like so:

$ wchar 'test
> test'
{'t','e','s','t','\n','t','e','s','t',0}

Edit: Some ideas that almost work:

echo -n "{" && echo -n "$1" | sed -r ":a;N;;s/\\n/\\\\n/;$!ba;s/((\\\\x[0-9a-fA-F]+)|(\\\\[0-7]{1,3})|(\\\\?.))/'\1',/g" && echo "0}"

Produces:

$ wchar 'test\n\\n\1234\x1234abg
test
test'
{test\n\\n\1234\x1234abg\ntest\ntest0}

While removing the ! :

echo -n "{" && echo -n "$1" | sed -r ":a;N;;s/\\n/\\\\n/;$ba;s/((\\\\x[0-9a-fA-F]+)|(\\\\[0-7]{1,3})|(\\\\?.))/'\1',/g" && echo "0}"

Produces:

$ wchar 'test\n\\n\1234\x1234abg
test
test'
{'t','e','s','t','\n','\\','n','\123','4','\x1234ab','g','\n','t','e','s','t',
test0}

This is close...

The first isn't performing the final replacement, and the second isn't correctly adding the last line

You can pre-filter before passing to sed . Perl will do:

$ set -- 'test1
> test2'
$ echo -n "$1" | perl -0777 -pe 's/\n/\\n/g'
test1\ntest2

This is a very convoluted solution, but might work for your needs. GNU awk 4.1

#!/usr/bin/awk -f
@include "join"
@include "ord"
BEGIN {
  RS = "\\\\(n|x..)"
  FS = ""
}
{
  for (z=1; z<=NF; z++)
    y[++x] = ord($z)<0x20 ? sprintf("\\x%02x",ord($z)) : $z
  y[++x] = RT
}
END {
  y[++x] = "\\0"
  for (w in y)
    y[w] = "'" y[w] "'"
  printf "{%s}", join(y, 1, x, ",")
}

Result

$ cat file
a
b\nc\x0a

$ ./foo.awk file
{'a','\x0a','b','\n','c','\x0a','\0'}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM