Заставить AWK обработать огромный fileset с единственным процессом

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

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

1
23.08.2018, 02:28
2 ответа

Один из вариантов, если ваши имена файлов не содержат кавычек или пробелов, состоит в том, чтобы сложить их вместе с помощьюcat:

printf '%s ' * | xargs cat | awk...

Приведенное выше просто позволяет обойти ошибку «слишком длинный список аргументов», используя встроенную функцию(printf)для печати каждого имени файла, которое затем отправляется в xargs, которая разбивает имена файлов на пакеты, которые затем отправляет в cat, вывод которого затем отправляется на awk.

Но :не используйте xargs

Если у вас есть доступный GNU awk (gawk)версии 4.1 или выше , где была введена динамическая загрузка модулей, он содержит расширение, которое может самостоятельно читать каталог, обходя проблему.

Вот пример программы gawk, которая будет открывать и читать файлы в любом каталоге, который вы ей передадите; затем вы должны явно читать из каждого интересующего вас файла. Преимущество состоит в том, что у вас есть единственная программа (GNU )awk, которая будет читать каждый файл.

@load "readdir"
@load "filefuncs"

BEGIN { FS = "/" }
{
        result = stat($2, statdata)
        if (statdata["type"] != "file")
                next
        FS = " "
        while(getline < statdata["name"] > 0) {
                #print $1
        }
        FS = "/"
}

Основной цикл скрипта перебирает все аргументы, заданные в командной строке -, и пытается открыть их как каталог. Результирующие поля::

  • $1 = номер инода
  • $2 = имя файла
  • $3 = тип файла

Затем мы используем функцию filefuncs statдля проверки типа файла. Если это не простой файл, мы пропускаем его. В противном случае мы возвращаем FSнормальное значение и используем getlineдля чтения файла. После того, как мы закончим с каждым файлом, мы сбрасываем FS обратно на /, чтобы он мог отделить имя следующего файла от readdir.

Я узнал о readdir gawk здесь и о статистике файловых функций gawk здесь .

0
28.01.2020, 00:30

Если аргументов слишком много, вам придется открывать и обрабатывать файлы самостоятельно. С awk, без использования каких-либо расширений, вы можете использовать эту (ту же идею, что и ответ Джеффа):

awk '{ filename = $0; while(getline < filename > 0) { print $0; }}'

Например,в сочетании с командой findнайти нужные файлы:

find /etc/ -maxdepth 1 -type f -perm -444 -size 1 | \
  awk '{ filename = $0; while(getline < filename > 0) { print filename ":" $0; }}'

Далее, в зависимости от версии awk, можно передать больше файлов для обработки , как описано здесь .

A program can alter ARGC and the elements of ARGV. Each time awk reaches the end of an input file, it uses the next element of ARGV as the name of the next input file. By storing a different string there, a program can change which files are read. Use "-" to represent the standard input. Storing additional elements and incrementing ARGC causes additional files to be read.

Для иллюстрации на примере:

find /etc/ -maxdepth 1 -type f -perm -444 -size 1 | \
  awk '
    # When reading from STDIN, assume it is a list of files to read
    FILENAME == "-" { ARGV[ARGC] = $0; ARGC += 1 }
    # When not reading STDIN, it is a file to process
    FILENAME != "-" { print "---", FILENAME ":" FNR ":" $0; }
    # These will run after every file, including STDIN, hence the check
    BEGINFILE { if (FILENAME != "-") { print ">>>", FILENAME; } }
    ENDFILE   { if (FILENAME != "-") { print "<<<", FILENAME, FNR, "lines"; } }'
1
28.01.2020, 00:30

Теги

Похожие вопросы