0

I'm trying to convert unicode literals into readable format. I'm using the -t flag to see what command xargs is going to run before it runs it. I see the following weirdness:

$ echo -n "\\\t\\\u0042\\\u0065\\\u006e" | xargs -t -I '{}' echo -e '"'{}'"'
echo -e "\t\u0042\u0065\u006e"
"       \u0042\u0065\u006e"

Yet when I run it manually:

$ echo -e "\t\u0042\u0065\u006e"
        Ben
$

The \t is being correctly processed in both examples. but the \u00XX values are being treated as a plain string in the first example but is being encoded correctly in the second example. I see the same weirdness when I use printf as well.


$echo -n "\\\t\\\u0042\\\u0065\\\u006e" | xargs -t -I '{}' printf \"{}\"
printf "\t\u0042\u0065\u006e"
"       printf: invalid universal character name \u0042
$ printf "\t\u0042\u0065\u006e"
        Ben

Any ideas on what's happening and how to fix it?

4
  • What shell are you using and does it have echo builtin? If so, try manually running $(which echo) -e "..." -- that'll be the one xargs is using Oct 28, 2020 at 2:25
  • The shell is bash 4.4. echo is at /bin/echo. Oct 28, 2020 at 4:04
  • bash has echo builtin, and printf also. Try /bin/echo -e "\u0042\u0065\u006e" and /bin/printf ""\u0042\u0065\u006e" and you'll find those give the same results as xargs Oct 28, 2020 at 20:54
  • Now it makes sense. Thank you. I would have never guessed there were two versions each of echo and printf floating about in my test problem. That solves my big issue of "why?" I was able to find a workaround for my conversion problem with this: var=$(echo -n "\\t\\u0042\\u0065\\u006e"); echo -e "$var". Oct 28, 2020 at 21:20

1 Answer 1

0

Dave is correct, the shell isn't involved, so the echo is /bin/echo, try this:


echo  "\\\t\\\u0042\\\u0065\\\u006e" | od -c

echo "\\\t\\\u0042\\\u0065\\\u006e" | xargs -t -I '{}' echo -e '"'{}'"'
 
# echo -e '"'\t\u0042\u0065\u006e'"'
/bin/echo -e '"'\\t\\u0042\\u0065\\u006e'"'

Result:

0000000   \   \   t   \   \   u   0   0   4   2   \   \   u   0   0   6
0000020   5   \   \   u   0   0   6   e  \n
0000031
"   \u0042\u0065\u006e"
"   \u0042\u0065\u006e"
echo -e "\t\u0042\u0065\u006e" 

Tried with online bash shell

1
  • Thanks for the clarification. I replied also to Dave above. Oct 28, 2020 at 21:21

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.