1

I have a text file in the below format . I need to remove the text between the first and second semicolon (delimiter ), but retain the second semicolon

$cat test.txt
abc;def;ghi;jkl
mno;pqr;stu,xxx

My expected output

abc;ghi;jkl
mno;stu,xxx

I tried using sed 's/^([^;][^;]*);.*$/\1/', but it removes everything after the first semicolon. I also tried with cut -d ';' -f2, this only give the 2nd field as output.

Cyrus
  • 84,225
  • 14
  • 89
  • 153

5 Answers5

3

Trying to fix OP's attempts here, with sed you could try following code. Simple explanation would be, create 1st back reference which has value till 1st occurrence of ; then from 1st ; to 2nd ; don't keep it in backreference and keep rest of the value in 2nd back reference. Finally while substituting substitute it with 1st and 2nd back reference values.

sed -E 's/^([^;]*);[^;]*;(.*)/\1;\2/' Input_file

OR as per Ed's comment please try following;

sed -E 's/^([^;]*);[^;]*/\1/' Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
3

You can do it directly by simply removing the 2nd occurrence of the characters in question, e.g.

sed 's/[^;]*;//2' test.txt

Example Use/Output

$ sed 's/[^;]*;//2' test.txt
abc;ghi;jkl
mno;stu,xxx

A thanks to @EdMorton for improvements here as well.

If you did want to use awk, you could simply replace the 2nd field with nothing as well, e.g.

awk -F';' '{sub(/;[^;]*/,"")}1' test.txt

(same output)

With a thanks to @EdMorton for the improvement to the original.

Or as Cyrus suggest with cut, deleting field 2, e.g.

cut -d';' -f-1,3- test.txt

(same output)

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • `cut -d';' -f2- test.txt` does not work as we expect for this question. It removes the first column, not the second. It essentially says "keep from column 2 and on". – billpcs Jun 03 '21 at 07:56
  • I had one more hair-brained `awk` scheme. What about looping over all fields and just not outputting the 2nd? A little longer, but avoids all potential issues? – David C. Rankin Jun 03 '21 at 09:04
  • That'd be fine too. Or with GNU awk you could use `gensub()` just like you use `sed`. – Ed Morton Jun 03 '21 at 09:07
3

You may use this sed:

sed 's/;[^;]*//' file

abc;ghi;jkl
mno;stu,xxx
anubhava
  • 761,203
  • 64
  • 569
  • 643
3

Using cut

cut -d";" -f2 --complement file
  • -d is for delimeter, i.e ";" in your case
  • -f is for field, i.e keep the fields listed
  • --complement is to reverse the selection, i.e remove the fields listed

So:

$ cat test.txt
abc;def;ghi;jkl
mno;pqr;stu;xxx

$ cut -d";" -f2 --complement test.txt
abc;ghi;jkl 
mno;stu;xxx
billpcs
  • 633
  • 10
  • 17
  • 3
    You should mention that will only work with GNU `cut`, not a POSIX `cut`. – Ed Morton Jun 03 '21 at 09:12
  • 1
    If the `--complement` option seems a bit unwieldy remember the option can be shortened to the first unambiguous possibility i.e `--comp` or even `--co`. – potong Jun 03 '21 at 12:02
0

super lazy awk solution

gawk/mawk/mawk2 'sub(/;[^;]+/,"")'

a more verbose solution but makes it clearer what it's doing

g/mawk 'BEGIN {FS=";+"; OFS=";"} ($2="")||($0=$0)&&($1=$1)'

clean out 2nd field, but since null string is assigned in, it returns 0 (false), thus requiring logical or || to continue.

$0=$0 plus $1=$1 to clean up extra ;, which will also print it.

RARE Kpop Manifesto
  • 2,453
  • 3
  • 11