Replacing individual characters with a pattern.

Given a paragraph of text which individual words have been prepended with an equals sign, I want to replace the individual characters in each of the marked words with blank spaces (two underscores and a space) for students to fill in -- a cloze passage that lets the students know how many letters are in each of the words they are required to fill.

As an example, something like:

Truth be told, this is the =closest
 I've =ever =gotten to a =college =graduation.

should give:

Truth be told, this is the __ __ __ __ __ __ __  
I've __ __ __ __     __ __ __ __ __ __  to a 
__ __ __ __ __ __ __ __ __ __.

another variation I would like to be able to get is :

Truth be told, this is the c __ __ __ __ __ __  I've e __ __ __  
g__ __ __ __ __  to a g __ __ __ __ __ __ __ __ __.

I'm not quite sure how to go about this but I suspect awk will be the tool to use.

What have you done so far?
The second version would be easier...

How would you know from when or what is to be substituted?

Try this...

#Variation 1
awk '{ for(i=1;i<=NF;i++) {
                if($i~"=") {
                        l=length($i)-1
                        if($i~"[\\.,]$"){
                          l=l-1; e=substr($i,l+2,l) }
                        for(j=1;j<=l;j++) p=p"_ ";
                        $i=p;printf $i e OFS;p="";e=""
                } else { printf $i OFS }
        }printf "\n" } ' input_file

#Variation 2
awk '{ for(i=1;i<=NF;i++) {
                if($i~"=") {
                        l=length($i)-1
                        if($i~"[\\.,]$"){
                          l=l-1; e=substr($i,l+2,l) }
                        s=substr($i,2,1);
                        for(j=2;j<=l;j++) p=p"_ ";
                        $i=p;printf s $i e OFS;p="";e=""
                } else { printf $i OFS }
        }printf "\n" } ' input_file

--ahamed

1 Like

Another variation:

#  cat x.txt
Truth be told, this is the =closest
 I've =ever =gotten to a =college =graduation.
# awk '{for (i=1;i<=NF;i++) { if ($i ~ /^=/) { $i=substr($i,2); gsub ("[[:alpha:]]","__ ", $i) }} print}' x.txt
Truth be told, this is the __ __ __ __ __ __ __
I've __ __ __ __  __ __ __ __ __ __  to a __ __ __ __ __ __ __  __ __ __ __ __ __ __ __ __ __ .
2 Likes

ahhhh!!!

I was trying everything for this gsub ("[[:alpha:]]","__ ", $i) .
Awesome code CarloM :slight_smile: And thanks for the info!
My code looks like junk! :smiley:

--ahamed

this is fun!

perl -pe 's/(?:=)(\w+)\w/\1__ /g ; 1 while s/(\w)(\w)((__ )+)/\1__ \3/' < input-text-file 

Truth be told, this is the c__ __ __ __ __ __ 
 I've e__ __ __  g__ __ __ __ __  to a c__ __ __ __ __ __  g__ __ __ __ __ __ __ __ __ .

[/code]

1 Like

Work brilliantly. Thank you.

---------- Post updated at 01:17 AM ---------- Previous update was at 01:11 AM ----------

Works brilliantly, too. Just one question. I use the bash shell and can usually repeat the previous command by using the up arrow. This command doesn't show up. When I press the up arrow, the command before it appears. What gives?

---------- Post updated at 01:23 AM ----------

[COLOR="\#738fbf"][SIZE=1]---------- Post updated at 01:26 AM ---------- Previous update was at 01:23 AM ----------

Works as advertised. Thanks. Pity I am illiterate in perl.

Dunno. Line-wrapping?

Also, modified for your second variation:

# awk '{for (i=1;i<=NF;i++) { if ($i ~ /^=/) { x=substr($i,2,1); $i=substr($i,3); gsub ("[[:alpha:]]","__ ", $i); $i=x" "$i }} print}' x.txt
Truth be told, this is the c __ __ __ __ __ __
I've e __ __ __  g __ __ __ __ __  to a c __ __ __ __ __ __  g __ __ __ __ __ __ __ __ __ .

Thanks for the second variation. This one shows up in the shell history. Go figure. :rolleyes: