Replace last n lines

Dear Friends,

Using centos 7 version.. I have a file content like this

if bld.env.SAMBA_DIR:
    bld.program(target='winexe-static',
        source='winexe.c svcinstall.c async.c winexesvc32_exe.c winexesvc64_exe.c',
        includes=bld.env.SAMBA_DIR + '/bin/default/include/public',
        cflags='-pthread -include ' + bld.env.SAMBA_DIR + '/bin/default/include/config.h',
        linkflags='-pthread',
        stlibpath=bld.srcnode.abspath() + '/smb_static/build',
        stlib='smb_static bsd z resolv rt',
        lib='dl gnutls'
        )

Where I need to replace last but two line to below

        stlib='smb_dynamic bsd z resolv rt',
        lib='dl ls'

how can i do it with unix command instead of manually editing file.

thanks in advance

Hello onenessboy,

Could you please try following once.

tac Input_file | awk 'FNR==2{sub("static","dynamic")} FNR==3{sub("gnutls","ls")} 1' | tac

In case you want to save output into Input_file itself then append > temp_file && mv temp_file Input_file in above code too.

Thanks,
R. Singh

2 Likes

Hi Ravinder,

Thanks much for help, but is there any way that we can replace nth line without any conditions to check ? as your solution checking for strings and then replace, but is there any way, I can directly remove last but two lines and replace entire line as per my previous post ? what I mean remove completely last but two line before in that input file and append/replace these two lines in that place. The reason being stlib value may contain another strings also at times so wanted to remove that line and append

stlib='smb_dynamic bsd z resolv rt',
lib='dl ls'

You could THANK people by hitting THANKS button on left corner of each post. Could you please try following.

tac Input_file | awk 'FNR!=2 && FNR!=3' | tac

Let me know if this helps you.

Thanks,
R. Singh

1 Like

Hi Ravinder,

I tried your solution here is what it displays..
stlib='smb_static bsd z resolv rt' this line still shows..

[root@xx-xx--xxx source]# tac reptest | awk 'FNR!=2 && FNR!=3' | tac
if bld.env.SAMBA_DIR:
    bld.program(target='winexe-static',
        source='winexe.c svcinstall.c async.c winexesvc32_exe.c winexesvc64_exe.c',
        includes=bld.env.SAMBA_DIR + '/bin/default/include/public',
        cflags='-pthread -include ' + bld.env.SAMBA_DIR + '/bin/default/include/config.h',
        linkflags='-pthread',
        stlibpath=bld.srcnode.abspath() + '/smb_static/build',
        stlib='smb_static bsd z resolv rt',

mean while i am trying head command too...let you know result

Hello onenessboy,

It is working fine for me as follows. I am attaching screen shot for same too.
Since NOT able to copy/paste screen shot here.

Thanks,
R. Singh

1 Like

Ok, as of now I figured it out with different command that is head -n to remove last 3 lines and append new lines with >>

[root@ip-xxxxx source]# head -n -3 reptest > tmp.txt && cp tmp.txt reptest
cp: overwrite �reptest'? y
[root@ip-xxxxxx source]# echo -e '\t'"stlib='smb_dynamic bsd z resolv rt'", >> reptest
[root@ip-xxxxxx source]# echo -e '\t'"lib='dl ls'", >> reptest
[root@ip-xxxxxx source]# echo -e '\t'")" >> reptest
[root@ip-xxxxx source]# cat reptest
if bld.env.SAMBA_DIR:
    bld.program(target='winexe-static',
        source='winexe.c svcinstall.c async.c winexesvc32_exe.c winexesvc64_exe.c',
        includes=bld.env.SAMBA_DIR + '/bin/default/include/public',
        cflags='-pthread -include ' + bld.env.SAMBA_DIR + '/bin/default/include/config.h',
        linkflags='-pthread',
        stlibpath=bld.srcnode.abspath() + '/smb_static/build',
        stlib='smb_dynamic bsd z resolv rt',
        lib='dl ls',
        )
1 Like
vim "-cnorm G2k ci'smb_dynamic bsd z resolv rt" "-cnorm Gk ci'dl ls" +wq reptest

You seem to want to automatically update some sort of source-code. There is a specialised utility for that, it is called patch . In general it is fed a diff -output file and applies this diff to a sourcce file. This is the common way to update the source in a source-rpm to a higher version. The update will contain all the diffs which, when applied to an older version, give you the newer version. The man page of patch is rather exhaustive, so i suggest to read it carefully. If there are still questions please do not hesitate to raise them.

If you just want to replace fixed lines with a fixed text you could create a "changes-file" that might look like this:

<line-nr>|replacement-text

i.e.

25|replacement1
27|replacement2

and feed it the following script, which just an infinitely dumb version of patch :

#! /bin/ksh

typeset    fIn="/some/input/file"
typeset    fOut="/some/output/file"
typeset    fChanges="/file/with/the/changes/as/mentioned"
typeset -i iLine=0
typeset    chLine=""
typeset    fTmp="/tmp/myscript.$$"


cp "$fIn" "$fTmp"
while IFS="|" read iLine chLine ; do
     if sed "$iLine"' s/.*/'"$chLine"'/' "$fTmp" > "$fOut" ; then
          cp  "$fOut" "$fTmp"
     else
          exit 1
     fi
done < "$fChanges"

exit 0

Notice that in this case the replacement text must not contain regexes, i.e. backreferences like \1

I hope this helps.

bakunin