bash-completion-tutorial icon indicating copy to clipboard operation
bash-completion-tutorial copied to clipboard

sed command not replacing/removing tabs

Open douglasdd opened this issue 4 years ago • 1 comments

((Thanks, https://iridakos.com/programming/2018/03/01/bash-programmable-completion-tutorial Is super-accessible, and very helpful!))

From this place in your doc

replace tabs with spaces ... sed to the rescue. ... fc -l -50 | sed 's/\t//' ...

Actually removes the first plain "t" character!

Instead, to replace 1 tab character with 1 space, the sed command you want is:

$ fc -l -50 | sed $'s/\t/ /'

Notes:

  • Bash '' strings do not do C-style escape sequences
    • (neither to "" strings in Bash)
    • only $'' bash strings process C-style escape sequences
      • (recall that echo -e "a\tb" TAB expansion is done inside the echo builtin code)
  • so sed sees '\t' in ARGV
    • which it interprets as:
      1. an unnecessary '\' character, then
      2. a plain 't' character
  • Your sed removes what it matches, it does not replace
  • Plain fc output already has 1 TAB and 1 SPACE between the num & command
  • ...So it's really not clear if you want 1 space or 2 in the end result

Full log:

## Raw `fc` output:
## (using `... | cat -vet` to show TAB chars as "^I")
$ fc -l -5 | cat -vet
57^I . ~/ds/env/complete-dothis.bash $
58^I . ~/ds/env/complete-dothis.bash $
59^I _comp_debug_dothis=1$
60^I . ~/ds/env/complete-dothis.bash $
61^I dothis fc -l -5 | sed $'s/\t/ /'$

## Your current sed command:
## (note "complee", not complete")
$ fc -l -5 | sed 's/\t//' | cat -vet
58^I . ~/ds/env/complee-dothis.bash $
59^I _comp_debug_dohis=1$
60^I . ~/ds/env/complee-dothis.bash $
61^I dohis fc -l -5 | sed $'s/\t/ /'$
62^I fc -l -5 | ca -vet$

## Fixed sed command:
$ fc -l -5 | sed $'s/\t/ /' | cat -vet
59  _comp_debug_dothis=1$
60  . ~/ds/env/complete-dothis.bash $
61  dothis fc -l -5 | sed $'s/\t/ /'$
62  fc -l -5 | cat -vet$
63  fc -l -5 | sed 's/\t//' | cat -vet$
[12:43:57 Sun Feb 14] X:0 !65

$ echo "${BASH_VERSINFO[@]}"
3 2 57 1 release x86_64-apple-darwin18
# Mac 10.14.6

# ...but same behavior w/ Bash 5 (from HomeBrew)
5 0 18 1 release x86_64-apple-darwin18.7.0

douglasdd avatar Feb 14 '21 12:02 douglasdd

so sed sees '\t' in ARGV which it interprets as: an unnecessary '' character, then a plain 't' character

I'm almost certain this is because you're on a mac, and it's not an issue with bash, but with sed. The single quotes in bash do pass the '\t' on as-is, but then it's up to sed to interpret it. GNU sed supports these backslash escape characters in patterns, but Apple's version of sed apparently does not, and so you need to use the shell's $'' pattern as a workaround.

Another option is use the 'ctrl+v ' key combo to insert a literal tab character directly into your sed command.

[AIUI, Apple has rejected the GNU v3 license, and so uses BSD-based versions of sed/awk/coreutilities/etc. instead, which lack all those deliciously useful GNU extensions Linux users tend to enjoy. I believe, however, that there are mac versions of the GNU utilities that you can install manually.]

Actually, sed is really the wrong tool to use here anyway. 'tr -d' is lighter, and designed exactly for this kind of job.

davinosuke avatar Apr 04 '21 23:04 davinosuke