Print everything before nth delimiter

I’m looking for a sed solution like the one here: Print everything after nth delimiter

sed -E 's/^([^]*[]){3}//' infile

but to extract the text before nth delimiter, instead of nth delimiter like the example. Something that works with all sed variants. And operate on all lines like the example.

The delimiter in this example is but could be for any other. Should work with any version of sed.

Asked By: Smeterlink

||

Why don’t you use cut?

cut -d '' -f 1-3 infile

With sed, instead of deleting the match, capture it and use a back-reference to replace the whole line with the captured group:

sed -E 's/(^([^]*[]){3}).*/1/' infile

Though that would also print the trailing backslash… To avoid that you could run

sed -E 's/(^([^]*[]){2}[^]*).*/1/' infile
Answered By: don_crissti

Using awk:

$ awk -v var=3 'BEGIN{FS=OFS="\"}
(NF>=var){ split($0,arr,OFS); 
$0=""; 
for (i=1; i<=var; ++i) $(NF+1)=arr[i];
print}'

To keep nth delimiter the following command may be used.

$ awk -v var=3 'BEGIN{FS=OFS="\"} 
(NF>=var){ for (i=1; i<=var; ++i) printf "%s%s", $i, OFS; print ""}'

$ nawk '(match($0, /^([^\]*[\]){3}/)) 
{ print substr($0,RSTART,RLENGTH)}'

With GNU awk:

The following command uses back-referencing a captured group. This is an awk command taken from this answer. Thanks to @don_crissti

$ awk -F "\" -v col=3 '(NF>=col){print gensub(/(^([^\]*[\]){3}).*/, "\1", "g")}'
Answered By: Prabhjot Singh

You could replace the nth delimiter with newline (which cannot otherwise occur in the pattern space) and then delete everything starting with that newline. Here for n == 3:

sed 's/delim/
/3; P; d'

Or if the nth delimiter must be retained in the output:

sed 's/delim/&
/3; P; d'

To skip the lines that don’t have n delimiters:

sed -n 's/delim/
/3; t1
d; :1
P'
Answered By: Stéphane Chazelas

a shorter awk:

awk NF=3 FS='\' OFS='\'
  • define input and output field separators
  • set number of fields to keep
Answered By: jhnc
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.