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.
    echo "Hello\tworld"
    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.
    echo -e "Hello\tworld"
    Hello   world

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

  • 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 Jul 18 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. – Paul_Pedant Jul 18 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 Jul 18 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 – roaima Jul 18 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 Jul 18 at 18:54

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
  • 1
    @Paul_Pedant really? Did you try it in bash? – user000001 Jul 18 at 17:28
  • 1
    Yes, I did ! printf 'Hello\tworld\n' | od -An -t a returns ` H e l l o ht w o r l d nl ` . No ascii sp in sight. Also same result in ksh. – Paul_Pedant Jul 18 at 17:31
  • 1
    @Paul_Pedant just tested in bash and definitely works $ printf 'Hello\tworld\n' |cat -A prints Hello^Iworld$ – user000001 Jul 18 at 17:32
  • 2
    Then your test is invalid. If you do it in the command line, the terminal expands the tab. Even then, they are not "real" spaces -- the terminal window just gets the cursor position moved over a bit further. It does not happen in a pipe or to a file. If it did, tab separated data would be impossible. Whitespace is not all spaces. If you don't like od, then pipe it to cat -vet and see those ^I markers. – Paul_Pedant Jul 18 at 17:39
  • 1
    And in what world is ^I identical to three spaces? The OP is under a delusion that shells expand tabs, and he is confusing that with the non-standard nature of the -e option. Getting a portable syntax to emit ascii TAB characters is not going to disabuse him of his misapprehensions. Reread the original post, especially the last line. – Paul_Pedant Jul 18 at 17:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.