Need to replace one string, in a file, with another string from a different file ...

Hi,
I have a requirement to extract a variable string (say S1) from a given file (say File-A), and look for a certain pattern to find another string (say S2) in another file (say File-B) and replace S2 with S1.

An example could be:
You have got two password shadow files -
1) shadow1
2) shadow2

These files are colon (":") seperated fields (like any "/etc/shadow" file has).
I now need to look for a user (say 'David'); user entry is the first field in both the shadow files (both of the shadow files are having multiple users along with the user 'David') and replace the second field in the shadow files (which is the actual encrypted password string) of file 'shadow1' with the corressponding field in file 'shadow2' for the user 'David.

Password strings could be of any lengths and may contain all kinds of possible characters.

An example of AWK/gawk script would be the most desired on which can be embedded/called from a bash script.

However any method of solving this problem using Linux bash will do well for me.

Thank you very much in advance.

Please provide a sample of input files and desired output.

my understanding about ur requirement is ...you are looking up the value from password file and matching with it on a different column...

awk -F":" 'NR==FNR{a[$1]=$2; next} NR!=FNR{if(a[$1])print $1," ",a[$1]; else print $0 }' file2 file1

this will list all the values of file1...:slight_smile:

Thank you very much for your response.
However, somehow I received a syntax error at the position of 'else'.

am sorry i dint get the error...
can you please give the complete error...
for the time being can you just try the following code

awk -F":" 'NR==FNR{a[$1]=$2; next} NR!=FNR{if(a[$1])print $1," ",a[$1]; }' file2 file1

Is it possible you left out the ; before the else? That would give a syntax error.

hi vi,

awk -F":" 'NR==FNR{a[$1]=$2; next} NR!=FNR{if(a[$1])print $1," ",a[$1]; else print $0 }' file2 file1

which semicolon you are pointing to...i dint get you ???
i hav executed this command and it is working fine for me...
file1:

abc: 123
def: 456
ghi: pwd3

file2:

sam: ddd
def: pwd2
ram: mbo
abc: pwd1

O/P:

abc  pwd1
def   pwd2

hope this solves your problem

@vi_curious i think you are new to scripting i guess semicolon(:wink: always means enter or new line so that shouldnt be a prob...

sample example files are:
//=====shadow1 (contains something like below)==========

David:$1$a6P/HWT1$3q/DkYchZEs4y420ESL6u.:14166:0:90:7:::
sarvani:$1$0wPwj2dB$GSHkbM9kcPZkGPTdKfZJP1:14293:0:90:7:::
stuart:$1$sPgpLdir$b9qcdXKeJ78zaZ2tpJuuA/:13924:0:90:7:::

//=============shadow1 (ends here)=======================

//=====shadow2 (contains something like below)==========

David:$1$FbP0lc8N$MIJ8outnkYyBedIYK7TJ6.:14500:0:90:7:::
sarvani:$1$0wPwj2dB$GSHkbM9kcPZkGPTdKfZJP1:14293:0:90:7:::

//=============shadow2 (ends here)=======================

Please note that password hashes of the user 'David' is different in shadow2.

What I need is a file in output called (say shadow3) as below

//=====shadow3 (contains something like below)==========

David:$1$FbP0lc8N$MIJ8outnkYyBedIYK7TJ6.:14166:0:90:7:::
sarvani:$1$0wPwj2dB$GSHkbM9kcPZkGPTdKfZJP1:14293:0:90:7:::
stuart:$1$sPgpLdir$b9qcdXKeJ78zaZ2tpJuuA/:13924:0:90:7:::

//=============shadow3 (ends here)=======================

Please note again that the output file contains a password hash from shadow2 file and rest is from shadow1.

awk -F: -v OFS=":" 'NR==FNR{_[$1]=$2;next}_[$1]{$2=_[$1]}1' shadow2 shadow1

As far as I can see there is only one "else" so it should be obvious which ; I mean. OP said he was getting syntax error at "else" and I am pointing out one possible reason for it. He would get the same syntax error if he had inadvertently used a , instead of the ; .

It is a problem if it's not there when it should be.

the output which got:

awk -F":" 'NR==FNR{a[$1]=$2; next} NR!=FNR{if(a[$1])print $1," ",a[$1]; else print $0}' shadow2 shadow1
David   $1$FbP0lc8N$MIJ8outnkYyBedIYK7TJ6.
sarvani   $1$0wPwj2dB$GSHkbM9kcPZkGPTdKfZJP1
stuart:$1$sPgpLdir$b9qcdXKeJ78zaZ2tpJuuA/:13924:0:90:7:::

i dono why are you getting the error ??? if you could paste the error that would be greatful

I ran your script on my Linux machine ; probably earlier I had a typo or something else.

Try this:

awk -F":" -v user="David" 'NR==FNR{a[$1]=$2; next}$1==user{$2=a[$1]}1' OFS=":" shadow2 shadow1 > shadow3

Regards

hi vi...

wen your replied
" Is it possible you left out the ; before the else? That would give a syntax error."

i have already posted two codes and i couldnt fig out which one u were pointing to...
moreover i thought you were asking me if the code was wrong...coz it was next to my reply... am sorry i dint get wat u were trying to explain at tat point...

The output is not what is required as you only print fields $1 and $2 if $1 exists in shadow2. Try my snippet above.

@ Praveen:

so is it working fine now ??

One pitfall of not quoting... but my comment was directed at OP and not at you. It is obvious he mistyped the command.... better to use copy/paste.

thx for pointing out ripat...
the following code will work fine:

awk -F":" 'NR==FNR{a[$1]=$0; next} NR!=FNR{if(a[$1])print a[$1]; else print $0}' shadow2 shadow1
David:$1$FbP0lc8N$MIJ8outnkYyBedIYK7TJ6.:14500:0:90:7:::
sarvani:$1$0wPwj2dB$GSHkbM9kcPZkGPTdKfZJP1:14293:0:90:7:::
stuart:$1$sPgpLdir$b9qcdXKeJ78zaZ2tpJuuA/:13924:0:90:7:::

check if this works fine

In that case the output file you gave is not correct. It should be:

David:$1$FbP0lc8N$MIJ8outnkYyBedIYK7TJ6.:14166:0:90:7:::
sarvani:$1$0wPwj2dB$GSHkbM9kcPZkGPTdKfZJP1:14293:0:90:7:::
stuart:$1$sPgpLdir$b9qcdXKeJ78zaZ2tpJuuA/:13924:0:90:7:::

This worked great for my requirements, Thanks Ripet.

---------- Post updated at 08:26 PM ---------- Previous update was at 08:21 PM ----------

I'm very much thankful to you known_d_unknown for your quick replies; it's outstanding and I really appreciate it. Thanks its working for me now.