26

I need to replace a slash character with a tab to I can extract a directory name using awk.

/path/to/some/USEFUL_INFORMATION/in/some/path

I tried doing this, but all it does is put a "t" at the from of my output.

sed -e 's/\//\t/g' filename

Any help would be appreciated.

DavidO
  • 13,812
  • 3
  • 38
  • 66
Lance Übercut
  • 269
  • 1
  • 3
  • 3
  • 2
    This appears to depend on the version of `sed`. Try `tr '/' '\t' < filename` and see what happens. – Beta Jun 15 '11 at 19:58
  • You don't need to replace `/` with `TAB` and feed it to `awk`. `awk` can simply do it on its own. – ssapkota Jun 15 '11 at 20:05
  • 1
    Come to think of it, how about `cut -f5 -d'/' < filename`? – Beta Jun 15 '11 at 20:15
  • The question is a mixture of a need and tentative solutions. The actual need seems to extract USEFUL_INFORMATION but it doesn't tell if e.g. there's always the same number of slashes before that, which changes the problem. Is replacing / with TAB part of a tentative solution... or the real question ? In the latter case there are related questions like http://stackoverflow.com/questions/1424126/replace-whitespaces-with-tabs-in-linux . – Stéphane Gourichon Jun 06 '13 at 07:42
  • `gsed -e 's/\//\t/g' filename` since GNU `sed` understands `\t`. On Mac, install with `brew install`. – Anton Tarasenko Oct 23 '17 at 20:24

10 Answers10

36

First, you can use another character as the s/// delimiter. The command

sed 's:ABC:DEF:g'

is equivalent for

sed 's/ABC/DEF/g'

It will make your command more readable because you'll not have to escape the slash.

Said that, some seds do not support character escaping such as \t. It happens to me a lot in Mac OS X, for example. My solution is to press Control+V and then the tab char:

sed 's:/:<Control+V><TAB character>:g'

The result in my machine is:

$ pwd
/Users/brandizzi/sandbox/demo/mydemo
$ pwd | sed 's:/:        :g'
    Users   brandizzi   sandbox demo    mydemo

However, if your intention is to put all path directories in awk variables $1, $2 etc. just declare the slash to be the field separator with awk -F flag:

$ pwd
/Users/brandizzi/sandbox/demo/mydemo
$ pwd | awk -F / '{print $3 " " $5}'
brandizzi demo
brandizzi
  • 26,083
  • 8
  • 103
  • 158
17

Try awk:

awk  '{gsub("/","\t",$0); print;}' filename
ssapkota
  • 3,262
  • 19
  • 30
10

To replace / with TAB using sed:

sed 's/\//\'$'\t/g' filename.txt

Generally, place \'$' before tab (\t) and newline(\n) characters. Works in bash.

To extract the directory name:

Personally, I'd use grok12's answer.

awk -F'/' '{print $5}' filename.txt
quietjen
  • 101
  • 1
  • 5
  • 1
    This should be marked as the correct (most direct, using just `sed`) answer. I also use `^V^I` but don't like non-visible characters in maintained script files that some editors could mess up. – karmakaze May 09 '20 at 16:05
  • and allows to do things like `s/\//\'$'\t\t\n/g` – Evhz Mar 29 '23 at 22:13
6

I found the answer, for me, here. I have MacOSX so I used the Control+v followed by Control+i.

sed -e 's/\/[CTR+V][CTR+I]/g' filename
Climbs_lika_Spyder
  • 6,004
  • 3
  • 39
  • 53
  • You can also use instead of ! tells the terminal to interpret the character literally instead of running one of the bound actions (e.g. Tab would usually try to autocomplete the current word, but this lets you insert a tab character directly) – Christopher Shroba Jul 24 '20 at 14:57
1

Try to put double quote(" ") around instead of single quote(' ') as shown in the following command.

sed -i "s/\//\\t/g" filename

Generally we use double quotes(" ") with the sed when we are dealing with the special characters.

As in your case you haven't escaped the \ in TAB character(\t).

AKs
  • 1,727
  • 14
  • 18
1

Another option is to use `printf "\t"` within sed:

sh -c 'echo test1 test2 | sed -E "s#(.*) (.*)#\2`printf "\t"`\1#g"'

The output is:

test2   test1

Here's to show it works for your own example:

sh -c 'echo /path/to/some/USEFUL_INFORMATION/in/some/path | sed "s#/#`printf "\t"`#g"'

Output:

path    to  some    USEFUL_INFORMATION  in  some    path
cnst
  • 25,870
  • 6
  • 90
  • 122
  • Closest answer to what [shellcheck suggest](https://github.com/koalaman/shellcheck/wiki/SC1012). [Great related answer](https://unix.stackexchange.com/a/145385/209677), – Pablo Bianchi Aug 19 '20 at 07:46
1

awk -F '/' '{print $5}' your_file

This prints USEFUL_INFORMATION

It defines the field separator to be /. Note that since your strings start with a / the first field is null so your field counts will be one more than you might think.

grok12
  • 3,526
  • 6
  • 26
  • 27
0

First as the others suggested, use another character as a delimiter. Second, use $'\t' outside of the quotes. Example with ; as a delimiter:

$ echo "/path/to/some/USEFUL_INFORMATION/in/some/path" | sed -e 's;/;'$'\t'';g'
path    to  some    USEFUL_INFORMATION  in  some    path
woodengod
  • 101
0

Use + as delimiters sed -e 's+/+\t+g'

echo 'path/to/something' | sed -e 's+/+\t+g'

// path     to     something

Edit: a simpler way to extract the path of a file:

dirname /path/to/file.txt
#output /path/to
Eric Fortis
  • 16,372
  • 6
  • 41
  • 62
0

Have a look at dirnameand basename

$ dirname /path/to/some/USEFUL_INFORMATION/in/some/path
/path/to/some/USEFUL_INFORMATION/in/some

$ basename /path/to/some/USEFUL_INFORMATION/in/some/path
path

awk can handle any separator, e.g. /:

$ echo /path/to/some/USEFUL_INFORMATION/in/some/path | awk -F"/" '{print $5}'
USEFUL_INFORMATION
Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130