awk
может эффективно выполнять то же самое, что и perl
, здесь немного проще , хотя реализации, отличные от GNU, могут тратить немного процессорного времени на ненужное разбиение (большого?) Текста file:
awk 'NR==FNR{a["\\["$1"\\]"]="["$2"]";next} {for(k in a) gsub(k,a[k]);print}' key.txt essay.txt
Поскольку вы запросили объяснение :
awk
работает, беря «сценарий», состоящий из пар шаблон-действие, затем считывает один или несколько файлов (или стандартный ввод) один 'запись' в то время, когда по умолчанию каждая запись является строкой, и для каждой записи она разбивается на поля по умолчанию с пробелами (включая табуляцию) и применяет сценарий, по очереди (если не указано иное), проверяя каждый шаблон (что часто смотрит на текущую запись и / или ее поля) и соответствует ли она выполнению действия (которое часто что-то делает с указанной записью и / или полями или с ними). Здесь я указываю два файла key.txt essay.txt
, чтобы он считывал эти два файла в указанном порядке, строка за строкой. Сценарий можно поместить в файл, а не в командную строку, но здесь я решил не делать этого.
первый шаблон - NR == FNR
. NR
- встроенная переменная, которая представляет собой номер обрабатываемой записи; FNR
аналогично номеру записи в текущем входном файле. Для первого файла ( key.txt
) они равны; для второго файла (и любых других) они не равны
первое действие {a ["\\ [" $ 1 "\\]"] = "[" $ 2 "]"; next}
. awk
имеет «ассоциативные» или «хешированные» массивы; arrayyname [subexpr]
где subexpr
- это строковое выражение, считывающее или устанавливающее элемент массива. $ номер
например $ 1 $ 2
и т. Д. Ссылаются на поля, а $ 0
ссылаются на всю запись. Как указано выше, это действие выполняется только для строк в key.txt
, поэтому, например, в последней строке этого файла $ 1
будет 3
и $ 2
] - это источник-три
, и в нем хранится запись массива с нижним индексом \ [3 \]
и содержимым [исходный-три]
; см. ниже, почему я выбрал эти значения. "\\ ["
и "\\]"
представляют собой строковые литералы, использующие escape-последовательности, фактические значения которых равны \ [
и \]
тогда как "[" "]"
- это просто []
, а строковые операнды без оператора между ними объединяются. Наконец, это действие выполняет next
, что означает пропустить оставшуюся часть сценария для этой записи, просто вернитесь к началу цикла и начните со следующей записи.
второй шаблон пуст, поэтому он соответствует каждой строке во втором файле и выполняет действие {for (k in a) gsub (k, a [k]); print}
.Конструкция for (k in a)
создает цикл, во многом как оболочки типа Борна в for i в this that other; сделать что-нибудь с $ i; done
, за исключением того, что здесь значения k
являются индексами массива a
. Для каждого такого значения он выполняет gsub
(глобальный заменитель), который находит все совпадения с заданным регулярным выражением и заменяет их заданной строкой; Я выбрал индексы и содержимое в массиве (см. Выше), чтобы, например, \ [3 \]
было регулярным выражением, которое соответствует текстовой строке [3]
и [source-three]
] - это текстовая строка, которую вы хотите заменять при каждом таком совпадении. gsub
по умолчанию работает с текущей записью $ 0
. После выполнения этой замены для всех значений в a
он выполняет print
, который по умолчанию выводит $ 0
в его нынешнем виде, со всеми необходимыми заменами.
Примечание: GNU awk (gawk), распространенный, особенно в Linux, но не универсальный, имеет оптимизацию, при которой фактически не выполняется разделение полей, если ничто в шаблонах или выполняемых действиях не требует значений полей. В других реализациях может быть потрачено небольшое количество процессорного времени, чего избегает метод cuonglm perl
, но если ваши файлы не огромны, это, вероятно, даже не будет заметно.
&
отправляет команду curl
в фоновый режим, где она будет выполняться при каждом запуске, оболочка не будет ее ждать (она печатает номер задания и PID ). Вместо этого оболочка продолжает выполнять echo
, которая, поскольку она встроена, вполне может работать быстрее, чем curl
, поэтому оболочка завершается с echo
и печатает подсказку до того, какcurl
выдает какие-либо выходные данные..
. вывод, который я получаю с помощью Bash:
bash ~ $ curl -d "asd" 0.0.0.0/abc & echo "abc";
[1] 26757
abc
bash ~ $ curl: (7) Failed to connect to 0.0.0.0 port 80: Connection refused
Подсказка в начале последней строки.
При нажатии Enter оболочка напечатает еще одно приглашение, после чего она также проверит, завершено ли фоновое задание, и напечатает примечание об этом:
[1]+ Exit 7 curl -d "asd" 0.0.0.0/abc
bash ~ $
Теперь я не уверен, что именно вы делаете, но из-за этого фоновые задания, выводящие на терминал, немного неудобны, поэтому вы можете перенаправить вывод curl
в другое место, или запустить его на переднем плане. Например. curl something; echo curl done
сначала запустит curl
, затем echo
и curl something && echo curl done
запустит только echo
, если curl
не выйдет из строя.