replace string in file.1 with line from file.2

Hello all, the title makes this sound simple, and maybe it should be.

This is by code:

#!/bin/sh
cp ch25.txt ch25.fn.tex
n=`grep -c '^\[' ch25_footnotes.txt`

for i in {1..$n}
do
        `grep '^\[$i\]' ch25_footnotes.txt > temp`
        r=`awk -F] '{print $2}' temp`
        `sed 's/\[$i\]/\\footnote{$r}/' ch25.fn.tex`
done

This is what I am trying to do. I have a file like this:

That contains a body of text with footnotes markers, that are of exactly that format [i]. Square brackets are not used otherwise in the text... at least no patters of the form [integer] exist except for footnote markers.

I have a another file of the footnote text, like this

What that code I wrote is attempting to do is:

  1. Create a copy of the body text to mess with.
  2. Count the number of footnotes that exist.
  3. Initiate a For loop that will generate an $i for every integer up to $n, the number of footnotes.
  4. grep the line starting with [$i] and save stick it into a temp file.
  5. use awk to grab only the text portion of the footnote (skipping the [$i] number at the beginning of the line) and store that in variable r.
  6. Finally, search the main file for the [$i] marker and add the footnote, alone with \footnote{} markup for latex.
  7. Repeat hundreds of times (-;

I am not all that great with scripting, but this is my thought process and what I have tried. Right now... nothing happens. I execute the script, and it just hangs, and I have to break the script.

In case you are wondering, I am just trying to typeset Marx's Das Kapital for posterity and easier reading. I do not plan on printing or distributing... just taking a freely available reading material and making it pretty.

Thank you!

PS, I notice that I forgot a semicolon after the for argument... I added that and it still does not run. Thank you!
PPS, I also realized that I should probably have back-ticked the grep and sed commands... but that also did not solve my problem.
PPPS, I am fixing the stupid errors in my code... I hope you don't decline to help me because they existed! lol

Alright, so this was an uninteresting problem, I guess... no hits at all except for my own! But, I did solve PART of the problem, so for what its worth I am going to explain that... I am sure I am not the only person to make this mistake.

In my grep command, I was trying to reference a variable integer stored in $i.
Grep was reading the $ independently, as a regular expression meaning "at the end of the line" I think... but at any rate, it was NOT looking for the variable $i and passing that into the argument.

To work around this:

for i in {1..5}
do 
    echo $i; #to make sure the for loop was working as expected.
    
    str="grep '^\[$i\]' ch25_footnotes.txt"; #I saved the whole thing as a string, which DOES 
                                             #interpret $i as a variable.  If I were to echo that 
                                             #command, it would have a number there 
                                             #rather than a $i.
   
    eval $str; #this actually runs the grep command
done

This works for the grep part... But I guess now the kink is in getting the for command to acknowledge the $n variable... :confused:

Meh... help would be welcome!

Here is what I have managed to come up with:

#!/bin/sh
cp ch25.txt ch25.fn.tex
n=`grep -c '^\[' ch25_footnotes.txt`
echo $n

#for i in {1..n};  ### This syntax was not working, for some reason

for ((i=1; i <= n ; i++))
do
        str="grep '^\[$i\]' ch25_footnotes.txt > temp"
#      echo $str
        eval $str
        r=`awk -F] '{print $2}' temp`
#      echo $r ## Up to here, things work as expected.
        str2="sed 's/\[$i\]/\\\footnote{$r}/' ch25.fn.tex"
        eval $str2
done

Now, the issue seems to be that it is dumping to standard output, rather than actually editing ch25.fn.tex. I dont really know why thats happening... and I THINK that it printed to stout 140 times, each with the footnote added to only that one number... I THINK that is what happened. To much output to sift through. I feel that I have narrowed down the problem to my sed command.

I have spent too much time playing around already. I hope someone finds this interesting or is sympathetic to my curiosity and helps me out!

$
$ cat ch25.txt
First there was nothing. Then there was Calvin[1].
blah blah blah
blah blah blah
"On a long enough timeline, the survival rate for everyone drops to zero" [2].
blah blah blah
"Dr. Livingstone, I presume?" [3]
blah blah blah
$
$ cat footnotes.txt
[1] A memorable quote from Bill Waterson's Calvin and Hobbes.
[2] Spoken by Tyler Durden, in Chuck Palahniuk's "Fight Club".
[3] By Henry Morton Stanley, on meeting Dr. David Livingstone near Lake Tanganyika on Nov. 10th, 1871.
$
$
$ perl -ne 'BEGIN {
>   open(FN,"footnotes.txt");
>   while(<FN>) {chomp; $fnote{$1}=$2 if (/(\[\d+\]) (.*)/)}
>   close(FN)}
> chomp;
> if (/(.*?)(\[\d+\])/) {print "$1\\footnote{$fnote{$2}}\n"}
> else {print $_,"\n"}' ch25.txt
First there was nothing. Then there was Calvin\footnote{A memorable quote from Bill Waterson's Calvin and Hobbes.}
blah blah blah
blah blah blah
"On a long enough timeline, the survival rate for everyone drops to zero" \footnote{Spoken by Tyler Durden, in Chuck Palahniuk's "FightClub".}
blah blah blah
"Dr. Livingstone, I presume?" \footnote{By Henry Morton Stanley, on meeting Dr. David Livingstone near Lake Tanganyika on Nov. 10th, 1871.}
blah blah blah
$
$

HTH,
tyler_durden

___________________________________________________________
"It's only after we've lost everything that we're free to do anything."

Wow, that worked like a charm and was less elaborate than my scheme. It'll take me a bit to understand what you did, I don't know perl at all, but it certainly got the job done. Thank you!

Chris

awk 'FNR==NR{id[$1]="{"substr($0,length($1)+2,length($0))"}";next}
{a=$0;b=match($0,/\[[0-9]+\]/);
if(b>0){
c=substr($0,RSTART,RLENGTH);o=substr($0,1,b-1);print o"\\footnote"id[c]
}
else print
}' footnotes.txt ch25.txt

cheers,
Devaraj Takhellambam