Posiadanie następujących w jednej z moich funkcji powłoki:
function _process () {
awk -v l="$line" '
BEGIN {p=0}
/'"$1"'/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
}
, więc gdy zostanie wywołany jako _process $arg
, $arg
zostanie przekazany jako $1
i użyty jako wzorzec wyszukiwania. Działa to w ten sposób, ponieważ skorupa rozszerza się $1
zamiast wzoru awk! Również l
może być używany wewnątrz programu awk, zadeklarowane z -v l="$line"
. Wszystko w porządku.
Czy w ten sam sposób można podać wzorzec wyszukiwania jako zmienną?
Obserwowanie nie będzie działać,
awk -v l="$line" -v search="$pattern" '
BEGIN {p=0}
/search/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
, ponieważ awk nie będzie interpretowany /search/
jako zmienna, ale dosłownie.
if (p) ...
$0 ~ pattern
i to nie działa, jednak z/'"$1"'/
tym działa !? : O$line
są pobierane, wyszukiwania wzorca odbywa się na wyjściuwhois $line
,$line
pochodzące z pliku na jakiś czas blokują.$line
- zrób to w swoim pytaniu, aby uzyskać prawidłowe formatowanie.Ma problem polegający na tym, że
awk
rozszerza sekwencje specjalne ANSI C (jak\n
dla nowej linii,\f
dla wysuwu formularza,\\
dla odwrotnego ukośnika i tak dalej) w$1
. Staje się więc problemem, jeśli$1
zawiera znaki odwrotnego ukośnika, które są powszechne w wyrażeniach regularnych (w GNUawk
4.2 lub nowszym problemem są również wartości zaczynające się@/
i kończące na/
). Innym podejściem, które nie cierpi z powodu tego problemu, jest napisanie go:To, jak źle będzie, będzie zależeć od
awk
wdrożenia.Wszystkie
awk
działają jednakowo dla prawidłowych sekwencji ucieczki:(treść
$a
przekazana w obecnej postaci)(
\\
zmieniono na\
i\b
zmieniono na znak cofania).źródło
\d{3}
znalezienie trzech cyfr, nie działałoby to zgodnie z oczekiwaniami, jeśli dobrze cię zrozumiałem?\d
których nie jest prawidłową sekwencją zmiany znaczenia C, która zależy odawk
implementacji (uruchom,awk -v 'a=\d{3}' 'BEGIN{print a}'
aby sprawdzić). Ale dla\` or
\ b, yes definitely. (BTW, I don't know of any awk implementations that understands
\ d` jako cyfra).\d' treated as plain
d 'd {3}, więc myślę, że w tym przypadku miałbym problem?ENVIRON["PATTERN"]
doPATTERN
zmiennej środowiskowej. Jeśli chcesz użyć zmiennej powłoki, musisz ją najpierw wyeksportować (export variable
) lub użyćENV=VALUE awk '...ENVIRON["ENV"]'
składni env-var, jak w mojej odpowiedzi.Wypróbuj coś takiego:
źródło
/regex/
w przypadku znalezienia wzorca, może to być dobre rozwiązanie. Spróbuję.Nie, ale możesz po prostu interpolować wzorzec na ciąg znaków cudzysłowów przekazywanych do awk:
Zauważ, że teraz musisz uciec od podwójnie cytowanego literału awk, ale wciąż jest to najprostszy sposób na osiągnięcie tego.
źródło
$pattern
zawiera spacje, mój przykład z góry będzie działał, ponieważ 1 USD jest chroniony podwójnymi cudzysłowami „1 USD”, ale nie wiem, co się stanie w twoim przypadku.'
, a następnie chroni$1
podwójne znaki cudzysłowu, a następnie przetwarza inny ciąg znaków pojedynczego cudzysłowu dla drugiej połowy programu awk. Jeśli dobrze rozumiem, powinno to mieć dokładnie taki sam efekt jak ochrona$1
zewnętrznych pojedynczych cudzysłowów - awk nigdy nie widzi podwójnych cudzysłowów, które umieszczasz wokół niego.$pattern
zawiera^/ {system("rm -rf /")};
, to masz duże kłopoty.Możesz użyć funkcji eval, która rozwiązuje w tym przykładzie zmienną nets przed uruchomieniem awk.
źródło