share
Unix & Linuxlinux command to process part of line before and after a pattern differently
[0] [2] sumina
[2020-04-16 06:52:38]
[ linux text-processing awk sed ]
[ https://unix.stackexchange.com/questions/580402/linux-command-to-process-part-of-line-before-and-after-a-pattern-differently ]

My original text is

11  2   CDTZ - b00264ab
36  37  CDTB - c2330001

I want output text to appear as

11  2   CDTZ - b0:02:64:ab
36  37  CDTB - c2:33:00:01

I have to add a colon after every 2 characters for the string that follows hyphen.

Is there any common text processing command to which I can instruct that

  1. All string before (and including) hyphen should be untouched.
  2. Insert colon after every 2 characters that follow hyphen.

In general, I have to process text before and after a pattern (hyphen here) differently.

My efforts so far:

Are the multiple spaces or single tabs between the columns? - Kusalananda
you can assume all separation as tab. - sumina
[+2] [2020-04-16 07:37:09] Siva [ACCEPTED]

Try this,

awk -v OFS='\t' '{gsub(/../,"&:",$NF); sub(/:$/,"",$NF);}1' file
11  2   CDTZ    -   b0:02:64:ab
36  37  CDTB    -   c2:33:00:01
  • gsub(/../,"&:",$NF) will add trailing : to each couple or charecters.
  • sub(/:$/,"",$NF) will remove the unwanted : at end of the last field which was added by previous gsub

(1) Yes, that works. Thanks. - sumina
adding 1 in the awk command seems a little cryptic.If I remove 1 and add print $0 after last semi colon then effect is same . The difference is that I can send output to a file while 1 in your case does not allow re-directing output to a file. What do you think ? - sumina
@sumina You can definitely just redirect the output to a new file with that awk command. Just add >newfile at the end. - Kusalananda
yeah, that works . Don't know why it didn't when I ran that previously. BTW, what does 1 refer to in your command ? - sumina
(1) @sumina It's a shortcut to writing { print }, which is the same as { print $0 }. Siva could just as well had used sub(...); print at the end of that { ... } block. - Kusalananda
ok. understood . - sumina
1
[+1] [2020-04-16 07:45:31] Kusalananda

Assuming that the hexadecimal number at the end is always eight characters:

$ sed 's/\(..\)\(..\)\(..\)\(..\)$/\1:\2:\3:\4/' file
11      2       CDTZ    -       b0:02:64:ab
36      37      CDTB    -       c2:33:00:01

That also works . Though, I intended to find a general manner to process text before and after a search pattern in line . So, awk solution is better . - sumina
(1) @sumina Well, your question was very specific about what you wanted to do, with specific data shown. If you have other data that does not fulfill the requirements of this answer, than you did not show it. My answer literally inserts a : between every second characters in the last column. - Kusalananda
As I said earlier - both answers work . I can do not have power to upvote and I can only mark one with tick. Did you gave -1 to question ? Thanks for listening . - sumina
@sumina I did not vote on anything relating to this question. - Kusalananda
when I posted, I got -1 then it became 0 after sometime and now it is again -1 . Stackexchange should tell user atleast who did it and be a little lenient . - sumina
@sumina See here about that: meta.stackexchange.com/questions/12984/… - Kusalananda
yeah, that tells it is anonymous . I suspect that there are experts who look down on beginners and quickly give negative votes . One should atleast leave a comment and a helpful opinion for user so that he won't repeat that mistake . - sumina
@sumina Our U&L Meta site contains a few questions about this, see e.g. unix.meta.stackexchange.com/search?q=why+downvoted - Kusalananda
ok . i try to ask general questions so that it is helpful for other users too . it sometimes happens that my requirement makes it more specific . - sumina
2