1

重複の可能性:
一致するキーフィールドに基づいて、テキストファイルの行を別のファイルの行に置き換えるにはどうすればよいですか?

次のファイルをマージし、FileB.txtの内容で共通行があるFileA.txtを上書きしたいのですが、FileA.txtをFileB.txtに完全に置き換えたくありません。

例えば:

ファイル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

ファイル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 =

この場合、マージ結果は次のようになります。

# 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 =

したがって、各行の「=」の前にあるものはすべてチェックして、FileA.txtとFileB.txtの間で一致させる必要があります。FileB.txtの「=」の後にFileA.txtと異なる場合は、FileB.txtにあるものはすべてFileA.txtに書き込む必要があります。

4

4 に答える 4

2

sort次のコマンドを試してください。

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

-t=:行を「=」のフィールドに分割するため、キーで並べ替えます

-k1,1:最初のフィールドで並べ替えます。複製(以下を参照)は指定されたソートフィールドにのみ依存するため、これは重要です。

-u:重複を排除します。2つの行が同じキーを持っている場合、最初の行だけが保持されます。

-s:安定ソート。ソートフィールドに基づいて2つの行が同一である場合、入力で最初に表示される行は出力で最初に表示されたままになります。

FileB.txt最初に入力ファイルのリストを入力することにより 、同じキーを共有している場合は、FileB.txtfrom行よりもfrom行が選択されるようになります。FileA.txt

于 2012-06-01T13:34:05.993 に答える
1

これが純粋なBASHの方法であり、一貫性とパフォーマンスが船外に投げ出されます。これは、重要なアプリケーションでは決して使用しないものです。

重要なアプリケーションでこれを使用している場合は、構成ライブラリを探すことを検討してください。たとえばJavaでは、Propertiesクラスがこれに最適です。これは単純なスクリプトでは機能しますが、正規表現を少し変更する必要がある場合があります。

プロパティファイルが適切にエスケープまたは引用されている場合、1行に複数の"="を含めることは違法ではありません。このスクリプトでは、問題が発生する可能性があります

#!/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
于 2012-06-01T07:22:03.417 に答える
1
#!/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]
        }
    }
}

次のように実行します。

$ ./interfacemerge FileB.txt FileA.txt
于 2012-06-01T11:36:07.493 に答える
0
{
    # 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
于 2012-06-01T10:32:18.023 に答える