Почему печать awk не удалось перенаправить?

Мне нужно объединить файл конфигурации 1 с файлом конфигурации 2. Если в файле 1 есть файл 2, добавьте его в конец файла 2. Я могу заменить печать на систему для исправления ошибки, но я не знаю, почему печать не работает.

Используйте print i" = " a[i] >> ARGV[2]; , не удалось добавить текст в конец текста

1.txt,Обратите внимание, что 3-я строка пустая:

key=5678
abc=000

  1. текст:
key=1234

test.awk:

#!/usr/bin/env -S gawk -F= -f
{
    key = gensub(/\s/, "", "g", $1);
    if (NR==FNR) {
        a[key]=$2;
    } else {
        b[key]=$2;
    }
}

END{
    for (i in a) {
        if (b[i] == "") {
            print "bi = empty, append to end of file:" i" = "a[i];
            print i" = "a[i] >> ARGV[2];
            # system("echo " i " = " a[i] ">>" ARGV[2]);
        } else if (a[i] != b[i]) {
            cmd = sprintf("sed -i -r 's@\\s*(%s)\\s*=.*@\\1=%s@' %s", i, a[i], ARGV[2]);
            system(cmd);
        }
    }
}

запустить ./test.awk 1.txt 2.txt результат :

$ ./test.awk 1.txt 2.txt 
bi = empty, append to end of file:=
bi = empty, append to end of file:abc=000
$ cat 2.txt 
key=5678
=

Почему abc=000 не добавляется в 2.txt? Если он изменен на system ("echo" I "=" a [i] ">" argv [2]), и снова все в порядке, есть ли ошибка в печати?

В руководстве gnu awk «5.9 Закрытие перенаправления ввода и вывода» требуется функция закрытия вызова, когда несколько команд работают с одним и тем же файлом, например, pipe или cmd, это очень плохо, поэтому я отказываюсь от печати >>, использую только system().

Наконец, я использую этот скрипт:

#!/usr/bin/env -S gawk -F"=|is" -f
# File:   sync_kernelconfig.awk
# Author: Edward.Tang
# Mail:   [email protected]
# Function: 同步文件1的内核配置到文件2

function set_value(array, comment, k, v)
{
    if (!/^\s*#/) {
        array[k]=v;
    } else {
        comment[k]=$2;
    }
}

{
    key = gensub(/#|\s/, "", "g", $1);

    if (key == "") next; # 跳过空行

    if (NR==FNR) {
        set_value(a1, c1, key, $2);
    } else {
        set_value(a2, c2, key, $2);
        line[key] = $0; # line data of file2
    }
}

END {
    for (i in a1) {
        if (a2[i] == "") {
            if (c2[i] == "") {
                system("echo " i " = " a1[i] ">>" ARGV[2]);
            } else {
                cmd = sprintf("sed -i -r 's~%s~%s=%s~' %s", line[i], i, a1[i], ARGV[2]);
                system(cmd);
            }
        } else if (a1[i] != a2[i]) {
            cmd = sprintf("sed -i -r 's~%s~%s=%s~' %s", line[i], i, a1[i], ARGV[2]);
            system(cmd);
        }
    }

    for (i in c1) {
        if (a2[i] != "") {
            cmd = sprintf("sed -i -r 's~%s~# %s is%s~' %s", line[i], i, c1[i], ARGV[2]);
            system(cmd);
        }
    }
}

What does 注意第三行是个空行 mean? Can you translate it, please

Sabito stands with Ukraine 10.12.2020 12:20

Также было бы неплохо добавить логику вашей программы вместе с образцом ввода и ожидаемым результатом в ваш вопрос для лучшего понимания.

RavinderSingh13 10.12.2020 12:25

Попробуйте изменить блок END на блок ENDFILE

Raman Sailopal 10.12.2020 12:36

@RamanSailopal После использования ENDFILE результатом будет key=5678 = key=5678 abc=000 =

Edward 10.12.2020 13:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В руководстве gnu awk «5.9 Закрытие перенаправлений ввода и вывода» требуется функция закрытия вызова, когда несколько команд работают с одним и тем же файлом, например, pipe или cmd, это очень плохо.

Поэтому мне нужно использовать:

print i" = "a[i] >> ARGV[2];
close(ARGV[2]);

или:

system("echo " i " = " a1[i] ">>" ARGV[2]);

Обратите внимание, что версия system() медленнее и крайне небезопасна — если ваши данные имеют $(somecommand), ваша оболочка будет запускать это как код. И вы не можете просто исправить это, добавив больше кавычек, потому что им можно противопоставить кавычки в данных.

Charles Duffy 14.12.2020 06:11

@CharlesDuffy Да, поэтому я сейчас рассматриваю возможность использования perl. Кажется, что мгновенное редактирование с помощью awk невозможно.

Edward 19.12.2020 06:29

Гораздо лучше было бы реструктурировать вашу программу так, чтобы она не состояла из редактирования на месте. Каждое такое редактирование перезаписывает весь ваш файл; это глубоко неэффективно.

Charles Duffy 19.12.2020 15:24

@CharlesDuffy Вы имеете в виду, что записываете все элементы, а затем записываете один раз в файл? У меня нет лучшей идеи.

Edward 21.01.2021 07:02

Другие вопросы по теме