LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   merging files in linux (https://www.linuxquestions.org/questions/linux-newbie-8/merging-files-in-linux-866615/)

dinakumar12 03-05-2011 12:01 PM

merging files in linux
 
Hi all,

Assume that i am having two files file1 and file2.

these were the contents of file1

Name=Dinesh
Age=24
sex=male
character=good
profession=admin

these were the contents of file2

Name=vino
Age=22
sex=female

Now i want to copy only the contents from file1 which were not in file2.

i.e. after copying my file2 content should look like this.

Name=vino
Age=22
sex=female
character=good
profession=admin

i.e. only the content which is not in file2 needs to be copied, remaining content should be undisturbed.

In linux is there a way to do this. If possible kindly post your suggestions.

Thanks in advance,
Dinesh.

Ignotum Per Ignotius 03-05-2011 12:55 PM

A quick 'n dirty method:

Code:

diff -y file[12] | sed '/< $/!s/=[^=]*=/=/g'
...Provided none of the fields end in the character < followed by a space!

PTrenholme 03-05-2011 01:12 PM

Note that the solution proposed by Ignotum per Ignoius assumes that your two files were literally named "file1" and "file2." If your actual names are different from those, the diff command should be written with the two file names following the -y option.

You can look at the output of man diff for a description of the diff command. (And, of course, man sed for a description of the stream editor into which the diff output is piped.)

Ignotum Per Ignotius 03-05-2011 01:30 PM

Quote:

Note that the solution proposed by Ignotum per Ignotius assumes that your two files were literally named "file1" and "file2." If your actual names are different from those, the diff command should be written with the two file names following the -y option.
Thanks for pointing that out: I'm a lazy typist... :hattip:

dinakumar12 03-05-2011 02:14 PM

Hi Ignotum,

I used your code,this is the output.

root@dinesh-laptop:~# diff -y file1 file2 | sed '/< $/!s/=[^=]*=/=/g'
Name=vino
Age=22
sex=female
character=good <
profession=admin <

But the contents is not copied to file2. it remains the same.

Ignotum Per Ignotius 03-05-2011 05:52 PM

Quote:

Hi Ignotum

I used your code,this is the output.

Code:

Name=vino
Age=22
sex=female
character=good <
profession=admin <


...As I said, quick 'n dirty... :)

Filter out the extraneous angle brackets with another application of sed.

Quote:

But the contents is not copied to file2. it remains the same.
The alteration is pretty simple --- just redirect to a temporary file and then move that over the original file.

Here's a one-liner that should do what you want:

Code:

diff -y file[12] | sed '/<$/!s/=[^=]*=/=/g' | sed 's/<$//g' > .tmpfile2 && mv .tmpfile2 file2
Test it first on some backup copies of your files, though!

dinakumar12 03-06-2011 09:45 AM

Hi,

Thank you that works fine. But i have one doubt is it necessary to redirect the output to a hidden file.

if thats the case can you please explain me why we cant redirect to a regular file.

Ignotum Per Ignotius 03-06-2011 11:06 AM

Quote:

Thank you that works fine.
Good show.

Quote:

But i have one doubt is it necessary to redirect the output to a hidden file.
The step of creating a temporary file is necessary --- you can't simply redirect the output of diff/sed to file2, as file2 is still being read line-by-line. However, it's not necessary to make the file hidden --- it's just my usual practice with temporary files.

Quote:

if thats the case can you please explain me why we cant redirect to a regular file.
You can redirect to a "regular" file: really, a hidden file is "regular" in every sense except that it's not (normally) listed by ls --- it doesn't have any special attributes in and of itself. The reason why (or at least one of the reasons why) I generally choose to hide temporary files containing redirected output is to reflect the fact that they exist only fleetingly as a stop-gap. You could just as easily have used an unhidden file. ...So yes, if it's bothering you, feel free to remove the period!

grail 03-06-2011 06:20 PM

Alternative:
Code:

awk -F"=" 'NR == FNR{_[$1]=$0;next}!($1 in _){print _[$1]}' file1 file2 > file3; mv file3 file2

dinakumar12 03-07-2011 12:39 AM

Hi grail,

Thanks for your reply,

i executed your code without redirecting to a file.and this is the output i got.

[root@localhost ~]# awk -F"=" 'NR == FNR{_[$1]=$0;next}!($1 in _){print _[$1]}' file1 file2



[root@localhost ~]#


Actually it looks empty.


Your suggestions please.

Aquarius_Girl 03-07-2011 12:47 AM

You can also try kdiff3, it is more user friendly! If you are using Kde, it will be
installed by default.

grail 03-07-2011 01:06 AM

Sorry about that ... appears I was on drugs with my thinking :(
This seems to do what you want:
Code:

awk -F"=" 'NR == FNR{_[$1]=$0;next}$1 in _{delete _[$1];print}END{for(x in _)print _[x]}' file1 file2

grail 03-07-2011 01:27 AM

Another alternative using the diffs and sed earlier, I am just not sure if appending straight away might cause issues:
Code:

diff -y file[12] | sed -n '/</s/ .*$//p' >> file2
It seems to work for me but I am sure there is some kind of danger ... unless of course diff closes the file after outputting information??

I am sure some guru will let us know :)

dinakumar12 03-07-2011 02:44 AM

Hi,


Thanks that works.Thanks to all especially to Ignotum.

Ignotum Per Ignotius 03-07-2011 05:10 PM

...Happy to have helped. :)

All the best.


All times are GMT -5. The time now is 10:57 PM.