1

How to replace random text between :50K and :53B in each line with CREDIT using shell?

The input is

{:32tyfddf:65 trfdfd :67 ghfdfd :50K:xxxxhh:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50K:yyyyhh:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50K:zzzzz:53B:fg :43:fg $
Palec
  • 12,743
  • 8
  • 69
  • 138
user3294574
  • 13
  • 1
  • 4

3 Answers3

2

Using awk

awk -F":50K|:53B" '{$2=":50KCREDIT:53B"}8' OFS="" file
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $

awk '{sub(/:50K.*:53B/,":50KCREDIT:53B")}8' file
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $

gnuawk

awk '{print gensub(/(:50K).*(:53B)/,"\\1CREDIT\\2","g")}' file
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
Jotne
  • 40,548
  • 12
  • 51
  • 55
  • The last two approaches are greedy. I do not think it is of any importance here, but it might be nice to mention.. – Håkon Hægland Feb 11 '14 at 09:29
  • 1
    @HåkonHægland Hei, how do I make them non greed. I tried to change `.*` with `[^:]+` but this does not work. – Jotne Feb 11 '14 at 10:04
  • I think it is difficult to make it nongreedy, see here: http://stackoverflow.com/questions/20783959/non-greedy-regular-expression-match-for-multicharacter-delimiters-in-awk . It is better to use perl nongreedy quantifier .*?, see answer of @mgsk . – Håkon Hægland Feb 11 '14 at 10:16
1
 sed 's/:50K.*:53B/:50KCREDIT:53B/g'

A basic sed replace expression:

s/what_to_look_for/what_to_replace_with/

g means "do it for all found patterns on the line" (you might want to skip that).

Usage: You use sed by either letting it read from stdin:

 cat path/to/your_text_file | sed 's/:50K.*:53B/:50KCREDIT:53B/g'

or by suplying the text file in which you want to replace as an argument

 sed 's/:50K.*:53B/:50KCREDIT:53B/g' path/to/your_text_file

Each will print the replace version to stdout. Neither will modify the original file in place.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • Getting following error:sed: command garbled: s/:50K.*53B/:50KCREDIT53B/g sh: MT.txt^M: not found sh: ^M: execute permission denied – user3294574 Feb 10 '14 at 21:39
  • You have to cat your text file into it, or do it like: sed 's/:50K.*:53B/:50KCREDIT:53B/g' path/to/your_text_file – Petr Skocik Feb 10 '14 at 21:42
  • 1
    Glad it helped. Note: `.*` also matches empty strings (zero or more of anything). If there must be something in between your prefix and postfix, change it to `..*`, which is sed's way of saying .+ like in the perl expression bellow (the perl solution is really better, as it allows more customization more easily). – Petr Skocik Feb 10 '14 at 22:07
  • This solution won't work if the random text contains also the string ":53B" How would you fix your solution in this case? – hongo Oct 04 '19 at 17:29
  • @hongo I wouldn't. Regexes tend to be greedy, so it just works. Try `sed 's/:50K.*:53B/:50KCREDIT:53B/g' <<<':50Kfoobar:53B:53B:53Bbaz:53B:53B'` – Petr Skocik Oct 04 '19 at 18:22
1

Using Perl:

perl -pi.bak -e 's/(\:50K).+?(\:53B)/${1}CREDIT${2}/g;' input_file

Basic usage:

s/replace_this/with_this/g;

(\:50K) and (\:53B) in replace this part are in parenthesis because these are so called capturing groups. You can refer to these capturing groups as ${1} and ${2} (or \1 and \2) in the with_this part, CREDIT as literal replacing whatever is in between ( .+?(\:53B) - means whatever character, whatever number of occurrences until :53B appears).

: is escaped because it's a metacharacter in regex.

Backup of the file will be saved to input_file.bak

Using your input, the output is:

$ cat input_file
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $
{:32tyfddf:65 trfdfd :67 ghfdfd :50KCREDIT:53B:fg :43:fg $

Hope it helps.

Michal Gasek
  • 6,173
  • 1
  • 18
  • 20