Linux: добавление значений в файлы, в конец отдельных строк и в конец файла, если есть «ключ» - PullRequest
0 голосов
/ 25 октября 2018

У меня есть один файл file1, в котором есть такие значения:

key1|value1|
key2|value2|
key3|value3|

У меня есть другой файл, file2, в котором есть значения на основе ключей, которые я хотел бы добавить для добавления в file1:

key2 value4
key3 value5
key4 value6

Я хотел бы добавить значения в file1 в строки, где «ключ» совпадает, и, если в file1 нет «ключа», просто добавив новый ключ & value внизу:

key1|value1|
key2|value2|value4|
key3|value3|value5|
key4|value6|

Похоже, что это можно сделать с помощью двух вызовов awk, но я недостаточно знаком с этим.Я также открыт для использования команд bash или shell.


ОБНОВЛЕНИЕ

Я нашел, что это работает

awk 'NR==FNR {a[$1]=$2; next} {print $1,$2,a[$1];delete a[$1]}END{for(k in a) print k,a[k]}' file2 file1

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

это ответ LOL ... ха-ха.Я в основном зацикливаюсь на их отслеживании и сортировке ... глупо, возможно, даже не то, что вы хотели бы использовать для bash, возможно ..

declare -a checked
checked=()

file="/tmp/file.txt"
> "${file}"

while IFS= read -r line1 ;do

    key1=$(echo $line1 | cut -d'|' -f1)

    if ! grep -qi ${key1} "/tmp/file2.txt" ; then
        echo "$line1" >> "${file}"
        continue
    fi

    while IFS= read -r line2 ;do

        key2=$(echo $line2 | cut -d' ' -f1)

        if ! grep -qi ${key2} "/tmp/file1.txt" ; then
            if ! [[ "${checked[@]}" =~ $key2 ]] ;then
                echo "$(echo $line2| awk '{print $1"|"$2}')|" >> "${file}"
                checked+=(${key2})
                continue
            fi
        fi

        if [[ "$key2" == "$key1" ]] ;then
            echo "${line1}$(echo $line2 | cut -d' ' -f2-)|" >> "${file}"
            continue
        fi

    done < "/tmp/file2.txt"
done < "/tmp/file1.txt"

sort -k2 -n ${file}
[[ -f "${file}" ]] && rm -f "${file}"

Вывод:

key1|value1|
key2|value2|value4|
key3|value3|value5|
key4|value6|
0 голосов
/ 25 октября 2018

Единственное отклонение от желаемого вывода состоит в том, что ключи из файла1, которых нет в файле2, не известны как AOT, поэтому они печатаются в конце, чтобы поддерживать полупериод:

awk -v first=data1.txt -f script.awk data2.txt
BEGIN {
    OLD=FS
    FS="|"
    while (getline < first)
        table[$1] = $0
    OFS=FS
    FS=OLD
}


!($1 in table) {
    queue[$1] = $0
}

$1 in table {
    id=$1
    gsub(FS, OFS)
    sub(/[^|]*\|/, "")
    print table[id] $0 OFS
    delete table[id]
}

END {
    for (id in table)
        print table[id]

    for (id in queue) {
        gsub(FS, OFS, queue[id])
        print queue[id] OFS
    }
}

key2|value2|value4|
key3|value3|value5|
key1|value1|
key4|value6|
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...