user22277
user22277

Reputation: 117

sed from pattern till end of file inside a for loop

I'm writing a bash script that would allow me to take a certain amount of text from a file and add some other text before that for a list of files.

directory=$(pwd)

    for f in *test.txt
    do


        filename=$(basename $f .txt)

        printf "%%sum=4 \n"> input.temp
        printf "file=$directory"/"$filename".txt" \n">> input.temp

        printf "some commands \n">> input.temp

        printf "\n" >> input.temp
        printf "description \n">> input.temp

        sed -n "/0 1/,$p" "$f" >> input.temp;


mv input.temp $filename.temp
done

I have a problem with the sed command inside the for loop. I looked around and people suggest adding double quotes which I did but to no avail. I think it might be the $p. I hope this is clear enough. If it's not, I'll try to explain better.

sed -n "/0 1/,$p" "$f" >> input.temp; does not work

sed -n '/0 1/,$p' "$f" >> input.temp; does not work

sed -n "/0 1/,\$p" "$f" >> input.temp; does not work

FYI I'm not trying to find something else that works. I want to fix this exact input. I sound like an asshole I'm sure.

Sample input

%sum=8
file=otherpath/filename.txt
some other commands

another description

0 1

                       0.36920852   -0.56246512    
                       0.77541848    0.05756533    
                       2.05409026    0.62333039    
                       2.92655258    0.56906375    
                       2.52034254   -0.05096652    
                       1.24167014   -0.61673008    
                      -0.60708600   -0.99443872    
                       0.10927459    0.09899803    
                       3.90284624    1.00103940    
                       3.18648588   -0.09239788    
                       0.93151968   -1.09013674    
                       2.50047427    1.30468389    
                       2.19361322    2.54108378   
                       3.18742399    0.34152442   
                       3.38679424    1.11276220   
                       1.56936488    3.27250306    
                       1.81754180    4.19564055    

     1 2 1.5 6
     2 3 1.5 
     3 4 
     4 5 1.5
     5 6 1.5 
     6 11 1.0
     7
     8
     9
     10
     11
     12
     13 16
     14 
     15
     16 17
     17

My desired output is basically this file from "0 1" till the end preceded by the stuff I put inside the printf.

UPDATE: If you're interested, the two scripts tripleee and Ed Morton provided work perfectly well. The problem in my script was me leaving out the -i option from the sed line (for inplace).

sed -n "/0 1/,$p" "$f" >> input.temp

should be replaced by

sed -ni '/0 1/,$p' "$f"

Upvotes: 0

Views: 1308

Answers (2)

Ed Morton
Ed Morton

Reputation: 203995

I see you updated your question and provided some additional information in your comments so try this, uses GNU awk 4.* for -i inplace:

awk -i inplace -v directory="$(pwd)" '
FNR==1 {
    print "%%sum=4 "
    print "file=" directory "/" FILENAME
    print "some commands "
    print ""
    print "description "
    found = 0
}
/0 1/ { found = 1 }
found
' *text.txt

If you don't have GNU awk then the technically correct way to do it is using xargs but it's simpler using a shell loop for the file manipulation (moving) part:

for file in *test.txt
do
    awk -v directory="$(pwd)" '
    FNR==1 {
        print "%%sum=4 "
        print "file=" directory "/" FILENAME
        print "some commands "
        print ""
        print "description "
        found = 0
    }
    /0 1/ { found = 1 }
    found
    ' "$file" > tmp && mv tmp "$file"
done

Upvotes: 1

tripleee
tripleee

Reputation: 189638

Like others have already commented, you basically just need to use single quotes instead of double, because $p in double quotes gets replaced with the value of the shell variable p by the shell, before sed executes (in practice, probably an empty string).

However, you might also want to investigate doing it all in sed. You might then instead stick with the double quotes (because there are other variables you do want to substitute) and instead escape the dollar sign in $p with a backslash to protect it from the shell.

directory=$(pwd)   # just do this once before the loop; the value doesn't change
for f in *text.txt; do
    # no braces
    filename=$(basename "$f" .txt)
    sed -n "1i\\
%sum=4\\
file=$directory/$filename.txt\\
some commands\\
\\
description
        /0 1/,\$p" "$f" >inputout.temp2  # no pointless separate temp file
done

In practice, I imagine you would like for the output file to be different in each iteration (maybe "$filename.temp" instead?) but what you do about that is up to you, obviously. As it is now, the file will contain the output from the last iteration.

Upvotes: 1

Related Questions