2

I have a script that is going to be executed by sh and bash on Debian Linux.

  1. When it is called by sh, the following echo command works perfectly, and replaces \t with 3 spaces. However, it fails when using #!/bin/bash.
    #/bin/sh
    echo "Hello\tworld"
    
    Output
    Hello   world
    
  2. When it is called by bash, the following echo command works perfectly, and replaces \t with 3 spaces. However, it fails when run with #/bin/sh.
    #/bin/bash
    echo -e "Hello\tworld"
    
    Output
    Hello   world
    

Is there any way where the same line command to replace \t sh or bash?

9
  • 2
    You never say how you run these scripts of yours. Note that the #!-line will be ignored as they are faulty (does not start with #!). Also note that neither command would ever output a single space!
    – Kusalananda
    Commented Jul 18, 2021 at 16:59
  • 3
    The issue is that echo is a built-in in both sh (which is usually a link to ksh) and in bash, and they are slightly differently specified. Using /bin/echo should at least be consistent. In any case, neither sh nor bash expands the TAB into three spaces: od -t a shows a Tab is output. Any expansion is done by the terminal emulator. If you echo into a file, it will be 12 bytes long (10 letters, one tab, one newline), not 14. Commented Jul 18, 2021 at 17:24
  • 1
    What do you mean by "replace \t with 3 spaces"? None of the commands you show actually replace the \t with anything. It is only that some interpret it and display it as a tab and others as a literal ` and t`, but none of them convert it to spaces. Can you explain what your final objective is here?
    – terdon
    Commented Jul 18, 2021 at 18:21
  • 2
    Your premise is faulty. If you "have a script that is going to be executed by sh and bash on Debian Linux" then it's a sh script and you should mark as such with the #!/bin/sh and not call it with bash Commented Jul 18, 2021 at 18:24
  • 2
    Summary: echo is like that, it behaves differently in different shells. Use printf 'Hello\tworld\n' if you want to output a tab and a newline. Like you get with Bash's echo -e, and Dash's echo , Dash being what your Debian very likely has as /bin/sh. If you really, seriously, want to output a particular number of spaces from the script, then that's not something either of those commands do. For that, you may want to ask another question.
    – ilkkachu
    Commented Jul 18, 2021 at 18:54

1 Answer 1

4

Assuming the tab is in the literal and not in a variable

printf 'Hello\tworld\n'

If the string is in the variable, then it is best to avoid putting the variable as the first argument of printf, because then you will need to escape any percentage marks (%) or backslashes (\ ) in the variable. The best way is to use %b as the format specifier in printf (Thanks to @Stéphane Chazelas)

$ a='hello\tworld'
$ printf "%b\n" "$a"
hello   world
$ printf "%b\n" "$a" | cat -A
hello^Iworld$
4
  • 1
    x="Hello\tworld" y=$(printf "${x}") works in bash as well shell giving output as with echo ${y} Hello world Commented Jul 19, 2021 at 6:02
  • @Pravin.2087 correct, but you should be careful if there are any percentage marks (%) or backslashes (\ ) in the variable. They will need to be escaped
    – user000001
    Commented Jul 19, 2021 at 6:16
  • 1
    You can do printf '%b\n' "$var" for $var to undergo the same backslash expansions as standard echo implementations do. Your sed approach would turn \\t to \<Tab> Commented Jul 19, 2021 at 7:23
  • @StéphaneChazelas: Thanks, that is really helpful
    – user000001
    Commented Jul 19, 2021 at 7:30

Not the answer you're looking for? Browse other questions tagged .