4

I would like to replace middle of word with ****.

For example :

ifbewofiwfib
wofhwifwbif
iwjfhwi
owfhewifewifewiwei
fejnwfu
fehiw
wfebnueiwbfiefi

Should become :

if********ib
wo*******if
iw***wi
ow**************ei
fe***fu
fe*iw
wf***********fi

So far I managed to replace all but the first 2 chars with:

sed -e 's/./*/g3' 

Or do it the long way:

grep -o '^..' file > start
cat file | sed 's:^..\(.*\)..$:\1:' | awk -F. '{for (i=1;i<=length($1);i++) a=a"*";$1=a;a=""}1' > stars
grep -o '..$' file > end
paste -d "" start stars > temp
paste -d "" temp end > final
fedorqui 'SO stop harming'
  • 228,878
  • 81
  • 465
  • 523
MataKiera
  • 53
  • 4
  • 1
    And what have you done so far ? Where are you blocked at ? What are you looking for exactly ? – vincrichaud Mar 15 '18 at 12:17
  • so far I managed to replace all but the first 2 chars with sed -e 's/./*/g3' or grep first 2 chars and then grep last 2 chars use sed to change the rest to ** and use paste to stick them back together. The goal is to replace all chars between first 2 and last 2 chars with * in all lines – MataKiera Mar 15 '18 at 12:24

4 Answers4

4

I would use Awk for this, if you have a GNU Awk to set the field separator to an empty string (How to set the field separator to an empty string?).

This way, you can loop through the chars and replace the desired ones with "*". In this case, replace from the 3rd to the 3rd last:

$ awk 'BEGIN{FS=OFS=""}{for (i=3; i<=NF-2; i++) $i="*"} 1' file
if********ib
wo*******if
iw***wi
ow**************ei
fe***fu
fe*iw
wf***********fi
fedorqui 'SO stop harming'
  • 228,878
  • 81
  • 465
  • 523
3

If perl is okay:

$ perl -pe 's/..\K.*(?=..)/"*" x length($&)/e' ip.txt
if********ib
wo*******if
iw***wi
ow**************ei
fe***fu
fe*iw
wf***********fi
  • ..\K.*(?=..) to match characters other than first/last two characters
  • e modifier allows to use Perl code in replacement section
  • "*" x length($&) use length function and string repetition operator to get desired replacement string
Sundeep
  • 19,273
  • 2
  • 19
  • 42
3

You can do it with a repetitive substitution, e.g.:

sed -E ':a; s/^(..)([*]*)[^*](.*..)$/\1\2*\3/; ta'

Explanation

This works by repeating the substitution until no change happens, that is what the :a; ...; ta bit does. The substitution consists of 3 matched groups and a non-asterisk character:

  • (..) the start of the string.
  • ([*]*) any already replaced characters.
  • [^*] the character to be replaced next.
  • (.*..) any remaining characters to replace and the end of the string.

Alternative GNU sed answer

You could also do this by using the hold space which might be simpler to read, e.g.:

h                                 # save a copy to hold space
s/./*/g3                          # replace all but 2 by *
G                                 # append hold space to pattern space
s/^(..)([*]*)..\n.*(..)$/\1\2\3/  # reformat pattern space

Run it like this:

sed -Ef parse.sed input.txt

Output in both cases

if********ib
wo*******if
iw***wi
ow**************ei
fe***fu
fe*iw
wf***********fi
Thor
  • 39,032
  • 10
  • 106
  • 121
1

Following awk may help you on same. It should work in any kind of awk versions.

awk '{len=length($0);for(i=3;i<=(len-2);i++){val=val "*"};print substr($0,1,2) val substr($0,len-1);val=""}'  Input_file

Adding a non-one liner form of solution too now.

awk '
{
  len=length($0);
  for(i=3;i<=(len-2);i++){
    val=val "*"};
  print substr($0,1,2) val substr($0,len-1);
  val=""
}
'  Input_file

Explanation: Adding explanation now for above code too.

awk '
{
  len=length($0);                           ##Creating variable named len whose value is length of current line.
  for(i=3;i<=(len-2);i++){                  ##Starting for loop which starts from i=3 too till len-2 value and doing following:
    val=val "*"};                           ##Creating a variable val whose value is concatenating the value of it within itself.
  print substr($0,1,2) val substr($0,len-1);##Printing substring first 2 chars and variable val and then last 2 chars of the current line.
  val=""                                    ##Nullifying the variable val here, so that old values should be nullified for this variable.
}
' Input_file                                ##Mentioning the Input_file name here.
RavinderSingh13
  • 101,958
  • 9
  • 41
  • 77