How do I merge FileA.txt and FileB.txt giving FileB.txt overwrite power using a bash script? [duplicate]

痞子三分冷 提交于 2019-12-23 02:53:42

问题


Possible Duplicate:
How can I replace lines in a text file with lines from another file based on matching key fields?

I want to merge the following files and I want the contents of FileB.txt to overwrite FileA.txt where there are common lines, but I don't want to completely replace FileA.txt with FileB.txt.

For example:

File A:

# cat FileA.txt 
interface.1.type = ethernet
interface.1 = A
interface.1.ip = 192.168.1.1
interface.1.netmask = 255.255.255.0
interface.1.dhcp = false

File B:

# cat FileB.txt 
interface.1 = B
interface.1.ip = 192.168.1.1
interface.1.netmask = 
interface.1.dhcp = true
interface.1.dhcp.range = 192.168.1.1,192.168.1.15
interface.1.extraline =

In this case The merge result should be:

# cat FileA.txt
interface.1.type = ethernet
interface.1 = B
interface.1.ip = 192.168.1.1
interface.1.netmask = 
interface.1.dhcp = true
interface.1.dhcp.range = 192.168.1.1,192.168.1.15
interface.1.extraline =

So anything before the '=' on each line should be checked and matched between FileA.txt and FileB.txt. If any after the '=' on FileB.txt differs from FileA.txt then whatever is in FileB.txt should be written to FileA.txt.


回答1:


Try this sort command:

sort -t= -k1,1 -us FileB.txt FileA.txt

-t=: split the lines into fields on the '=', so you are sorting on the keys

-k1,1: sort on the first field. This is important, as duplication (see below) depends only on the specified sort field.

-u: eliminate duplicates. If two lines have the same key, only the first is kept.

-s: stable sort. If two lines are identical based on their sort field, the line that is seen first in the input remains first in the output.

By putting FileB.txt in the list of input files first, you ensure that the line from FileB.txt is chosen over the line from FileA.txt if they share the same key.




回答2:


Here's the pure BASH way, consistency and performance are thrown overboard. This is something you would never use in a critical application.

If you are using this in a critical application, consider looking for a configuration library. In Java for instance, the Properties class is great for this. This works for simple scripts though, you might have to change the regular expression a bit.

It's not illegal for property files to contain more than one "=" on one line if properly escaped or quoted. In this script it might cause problems

#!/bin/bash
FILEA="filea.txt"
FILEB="fileb.txt"
RESULT="filec.txt"
:> $RESULT

while read line; do
    ELEM=$(echo $line | perl -pe 's/\s*\=.*?$//gi')
    FILEBLINE=$(grep "^\s*$ELEM" $FILEB)
    if [[ -n $FILEBLINE ]]; then
        echo $FILEBLINE >>$RESULT
    else
        echo $line >>$RESULT
    fi
done < $FILEA



回答3:


#!/usr/bin/awk -f
BEGIN {
    FS = " = ?"; OFS = " = "
}

NR == FNR {
    attrib[$1] = $2
    printed[$1] = 0
    next
}

(! ($1 in attrib)) {
    print
}

$1 in attrib && $2 != attrib[$1] {
    print $1, attrib[$1]
    printed[$1] = 1
}

END {
    for (i in printed) {
        if (! printed[i]) {
            print i, attrib[i]
        }
    }
}

Run it like this:

$ ./interfacemerge FileB.txt FileA.txt



回答4:


{
    # print the fileA settings not in fileB
    awk -F= 'NR==FNR {lhs[$1]; next} !($1 in lhs)' fileB.txt fileA.txt

    # then print all of fileB
    cat fileB.txt

    # then write to a new file and overwrite fileA
} > newfile && mv newfile fileA.txt


来源:https://stackoverflow.com/questions/10845601/how-do-i-merge-filea-txt-and-fileb-txt-giving-fileb-txt-overwrite-power-using-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!