2

My problem

I have a file with items, one per line. The item contains at least one dash, and I would like to remove the last dash and the words that follow. For example:

item asdkalqndla-asdnkfsv-324we-blueray
item asda-vbght564e-dfg-redapple
item gefdsc-fgy-543-5trr-floatingvanilla

Should give:

item asdkalqndla-asdnkfsv-324we
item asda-vbght564e-dfg
item gefdsc-fgy-543-5trr

What have I tried

sed 's/\-.*$//' lines.txt

Which gives

item asdkalqndla
item asda
item gefdsc

Because the regex is greedy, and consumes everything from the first dash onwards.

My question

How can I remove all characters from the last - in a string till EOL?

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
Adam Matan
  • 128,757
  • 147
  • 397
  • 562
  • Possible duplicate of [Display all fields except the last](https://stackoverflow.com/questions/13857836/display-all-fields-except-the-last) – Benjamin W. Nov 12 '17 at 18:21

4 Answers4

3

With awk:

$ awk '{sub(/-[^-]*$/,""); print}' file
item asdkalqndla-asdnkfsv-324we
item asda-vbght564e-dfg
item gefdsc-fgy-543-5trr
dawg
  • 98,345
  • 23
  • 131
  • 206
2

Simple negation using ^\- solved the problem:

$ sed 's/\-[^\-]*$//' lines.txt
item asdkalqndla-asdnkfsv-324we
item asda-vbght564e-dfg
item gefdsc-fgy-543-5trr

This way, sed replaces a dash followed by anything-but-dash till the end of the line.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
Adam Matan
  • 128,757
  • 147
  • 397
  • 562
2

Following simple awk may help you in same.

awk -F"-" 'NF{NF=(NF-1)} 1' OFS="-"   Input_file

Output will be as follows.

item asdkalqndla-asdnkfsv-324we
item asda-vbght564e-dfg
item gefdsc-fgy-543-5trr

Explanation: -F"-": Making field separator as - for each line for Input_file.

NF{NF=(NF-1)}: awk has out of the box NF variable which has number of fields for any line, since we don't text after last occurrence of - and field separator is -, by mentioning NF, we are checking if a line is NOT EMPTY. decrementing the number of field's value with 1 so that we will NOT get the last field.

1: awk works on method of condition then action so making condition part TRUE here by mentioning 1 here and not mentioning any action here so by default print of current line will happen.

OFS="-": Making OFS output field separator as "-" here so that - will come in output.

EDIT: Shorter versions of decrementing NF too as follows.

awk -F"-" 'NF{NF-=1} 1' OFS="-"  Input_file

OR

awk -F"-" 'NF{NF--} 1' OFS="-"  Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
1

This might work for you (GNU sed):

sed 's/\(.*\)-.*/\1/' file

Used greed to find the last - and replace the whole line with what came before it.

potong
  • 55,640
  • 6
  • 51
  • 83