Как идентифицировать шаблон, содержащий вложенные параметры внутри него

Современные ядра Linux (выше 4.1 или 4.2 )поддерживают вставку данных в начало файла с помощью системного вызова fallocate()с FALLOC_FL_INSERT_RANGEв файловых системах ext4 и xfs. По сути, это операция логического сдвига :: данные логически перемещаются по более высокому смещению.

Существует ограничение в отношении детализации диапазона, который вы хотите вставить в начало файла. Но для текстовых файлов вы, вероятно, можете выделить немного больше, чем требуется (до границы детализации )и заполнить пробелами или возвратом каретки, но это зависит от вашего приложения

Я не знаю какой-либо доступной утилиты Linux, которая манипулирует размерами файлов, но несложно написать :получить дескриптор файла и вызвать fallocate()с соответствующими аргументами. Дополнительные сведения см. на справочной странице системного вызова fallocate:http://man7.org/linux/man-pages/man2/fallocate.2.html

.

2
02.10.2020, 12:45
3 ответа

Perl спешит на помощь!

perl -MText::Balanced=extract_bracketed \
     -ne 'if (/length(\(.*)/) {
              ($arg) = (extract_bracketed(($1 =~ /\((.*)\)/)[0]))[1];
              print "length(cast($arg as string))\n";
          } else { print }' -- input.file > output.file

Он использует основной модуль Text ::Balanced , который извлекает из строк подстроки со сбалансированными разделителями.

1
18.03.2021, 23:00

Использование perlи рекурсивного сопоставления:

$ cat ip.txt
length(bill_cycle)
length(some(somethiing))

$ perl -pe 's/length(\(((?:[^()]++|(?1))++)\))/length(cast($2 as string))/' ip.txt 
length(cast(bill_cycle as string))
length(cast(some(somethiing) as string))

См. https://www.rexegg.com/regex-recursion.html, чтобы узнать, как работает рекурсия.

1
18.03.2021, 23:00

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

BEGIN { 
    p = "length"
}

{
    row = $0
    while (row ~ p"\\(") {
        # get the substring from pattern to the end of the line
        # and split to array with closing parenthesis separator

        x = substr(row, index(row,p) + length(p))
        split(x, a, ")")
        res = p

        # loop for array items and append them to substring
        # until we have a string with same number of
        # opening and closing parentheses.

        for (i=1;i<=length(a);i++) {

            res = res a[i] (i==length(a)? "": ")")

            if (gsub(/\(/,"(",res) == gsub(/\)/,")",res)) {
                print res
                break
            }
        }
        
        # will test again the rest of the row
        row = substr(x, length(p))
    }
}

Некоторые базовые тесты

> cat file
some text length(a(b)) testing another occurence length(a))
function(length(c(d(e(f(1), 2)))) testinglength(x)
x length(y))
x length(((y))
length(length(1))

> awk -f tst.awk file
length(a(b))
length(a)
length(c(d(e(f(1), 2))))
length(x)
length(y)
length(length(1))
0
18.03.2021, 23:00

Теги

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