45

My file looks like this

abc ||| xyz ||| foo bar
hello world ||| spam ham jam ||| blah blah

I want to extract a specific column, e.g. I could have done:

sed 's/\s|||\s/\\t/g' file | cut -f1

But is there another way of doing that?

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
alvas
  • 115,346
  • 109
  • 446
  • 738
  • 4
    Is this what you look for? [How to make the 'cut' command treat several sequential delimiters as one?](http://stackoverflow.com/questions/4143252/how-to-make-the-cut-command-treat-several-sequential-delimiters-as-one) – fedorqui Aug 22 '14 at 12:47
  • Does this answer your question? [How to make the 'cut' command treat same sequental delimiters as one?](https://stackoverflow.com/questions/4143252/how-to-make-the-cut-command-treat-same-sequental-delimiters-as-one) – dsimic Aug 22 '23 at 02:32

2 Answers2

56

Since | is a valid regex expression, it needs to be escaped with \\| or put in square brackets: [|].

You can do this:

awk -F' \\|\\|\\| ' '{print $1}' file

Some other variations that work as well:

awk -F' [|][|][|] ' '{print "$1"}' file
awk -F' [|]{3} ' '{print "$1"}' file
awk -F' \\|{3} ' '{print "$1"}' file
awk -F' \\|+ ' '{print "$1"}' file
awk -F' [|]+ ' '{print "$1"}' file

\ as separator does not work well in square brackets, only escaping, and many escape chars :)

cat file
abc \\\ xyz \\\ foo bar

Example: 4 \ for every \ in the expression, so 12 \ in total.

awk -F' \\\\\\\\\\\\ ' '{print $2}' file
xyz

or

awk -F' \\\\{3} ' '{print $2}' file
xyz

or this but it's not much simpler

awk -F' [\\\\]{3} ' '{print $2}' file
xyz

awk -F' [\\\\][\\\\][\\\\] ' '{print $2}' file
xyz
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Jotne
  • 40,548
  • 12
  • 51
  • 55
  • 11
    Or just `{print $1}`? – fedorqui Aug 22 '14 at 13:53
  • 6
    A breakdown explaining how it works would be nice. Especially it'd be nice to specify that it's the `$1` that needs to be changed to get a different column. – Vala Feb 18 '16 at 15:22
  • 6
    The `$0` holds the entire line, so `$0=$1` replaces the line with the first field. The `1` (anything that evaluates to true) after `{}` causes the line to be printed. – jrm Mar 25 '16 at 18:30
  • 2
    I had to do `awk -F ' \\|\\|\\| ' '{print $1}'` – e9t Apr 12 '18 at 13:25
-2

You can use awk to do it -

$ awk 'BEGIN {FS=" \|\|\| ";}{print $1}' file

Replace $1 with $2, $3, etc.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
xitkov
  • 9
  • 2
    Running this command, you get: `awk: cmd. line:1: warning: escape sequence `\|' treated as plain `|' – Jotne Aug 22 '14 at 13:50