0

I have following text

foo-11.11-fo.o-foo-bar

bar-foo-11.11-22.11

I want to remove last strings that have two "-".

Expected output:

foo-11.11-fo.o

bar-foo

I have tried multiple methods using cut, but nothing works.

2
$ cat ip.txt 
foo-11.11-fo.o-foo-bar
bar-foo-11.11-22.11

$ rev ip.txt
rab-oof-o.of-11.11-oof
11.22-11.11-oof-rab

$ rev ip.txt | cut -d- -f3- | rev
foo-11.11-fo.o
bar-foo

Reverse each line, then use cut to select all fields except first two and then reverse the output again


You can also use perl, but would print empty lines if any input line has less than 3 fields

$ perl -F'-' -lane 'print join "-", @F[0..$#F-2]' ip.txt 
foo-11.11-fo.o
bar-foo

Specify - as input delimiter and then print all but last two fields

  • rev that's what I missed. thanks a lot, working great. – Buvanesh Kumar Sep 25 '17 at 12:18
4

Using sed:

$ sed 's/-[^-]*-[^-]*$//' file
foo-11.11-fo.o
bar-foo

This will remove -X-X at the end of every line in file, where X is any string that does not include a -.

If the strings are in a shell variable:

$ s='foo-11.11-fo.o-foo-bar'
$ printf '%s\n' "${s%-*-*}"
foo-11.11-fo.o

$ s='bar-foo-11.11-22.11'
$ printf '%s\n' "${s%-*-*}"
bar-foo

or in a bash array:

$ s=( 'foo-11.11-fo.o-foo-bar' 'bar-foo-11.11-22.11' )
$ printf '%s\n' "${s[@]%-*-*}"
foo-11.11-fo.o
bar-foo

This removes anything matching the pattern -*-* at the end of the string in the variable s through a suffix pattern match/removal. In the case where s in an array, the removal is done on all elements of the array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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