Nie mogę pojąć, jak uciec przed wszystkim, używając awk.
Muszę ująć każde wejście ciąg znaków z pojedynczymi cudzysłowami, np.
input string1 string2 string3 output "string1" "string2" "string3"
Walczyłem z ucieczką " " $0
i wszystkim innym i po prostu nie mogę zrobić to działa. Albo $ 0 jest przekazywane bezpośrednio do basha, albo dzieje się coś innego.
Komentarze
- Podobne pytanie dla superużytkownika .
Odpowiedź
Oto kilka sposobów:
-
użyj ósemkowych sekwencji ucieczki. W systemach opartych na ASCII, gdzie
"
jest zakodowane jako bajt 39 (ósemkowe 047), to będzie:awk "{print "\047" $0 "\047"}" input "string1" "string2" "string3"
-
przekazuj cytat jako zmienną
$ awk -v q=""" "{print q $0 q}" input "string1" "string2" "string3"
Komentarze
-
"\047"
nigdy nie przyszło mi do głowy. Wow. Dziękuję. - O r zapisz swój skrypt awk w pliku
script.awk
do wykonania jakoawk -f script.awk input
, a następnie możesz po prostu wykonać{ print "'" $0 "'" }
lub{ printf "'%s'\n", $0 }
. Brak możliwości użycia'
sw skrypcie'
-delimited jest problemem powłoki, a nie awk. - Każdy ósemkowy, który uciekł z man ascii, jest dobry w awk. Nawet
\000
dla NUL (w GNU / awk, ale nie mawk) i\042
dla"
. - Polecam dodanie # 3: uniknij cudzysłowu na poziomie powłoki:
awk '{ print "'\''" $0 "'\''" }' input
i # 4 użyj cudzysłowów na poziomie powłoki:awk "{print \"'\" \$0 \"'\" }" input
. Ponieważ jest to akceptowana odpowiedź i zawiera już listę wielu metod, równie dobrze może zawierać również te alternatywy.
Odpowiedź
W kodzie awk po prostu umieść apostrof w podwójnych cudzysłowach. Możesz łączyć łańcuchy, umieszczając je obok siebie (zestawienie), bez względu na to, jak te ciągi są skonstruowane (literał, zmienna, odwołanie do pola, wyrażenie w nawiasach,…).
{ print """ $0 """ }
Jeśli ten kod awk jest zawarty w skrypcie powłoki, a kod awk znajduje się w pojedynczym cudzysłowie, musisz zorganizować przekazanie pojedynczy cudzysłów dla awk. Użyj pojedynczego cudzysłowu-odwrotnego ukośnika-pojedynczego-cudzysłowu-pojedynczego cudzysłowu "\""
, aby umieścić pojedynczy znak cudzysłowu w literał powłoki w pojedynczym cudzysłowie.
awk "{ print ""\""" $0 ""\""" }"
Alternatywnie, wyrażaj kod awk bez użycia pojedynczy znak cudzysłowu. Możesz użyć odwrotnego ukośnika, po którym następują trzy cyfry ósemkowe, aby przedstawić dowolny znak w literale łańcuchowym w awk. Pojedynczy cudzysłów w systemach opartych na ASCII to „s \047
.
awk "{ print "\047" $0 "\047" }"
Komentarze
-
awk '{ print "'\''" $0 "'\''" }'
to po prostu szalone. - @ ArtemS.Tashkinov To ' jest również zdecydowanie lepszym rozwiązaniem, jeśli chodzi o przenośność, i uważam, że jest bardziej zrozumiałe dla kogoś, kto zna powłokę tak dobrze, jak powinien, jeśli ' używają powłoki niż ósemkowych znaków ucieczki.
'\''
to coś, co każdy, kto wykonuje skrypty powłoki, powinien internalizować jako sposób na uniknięcie pojedynczych cudzysłowów w ciąg znaków powłoki w pojedynczych cudzysłowach, zwłaszcza, że ciągi w apostrofach są solidnym / przenośnym / najbezpieczniejszym sposobem na uniknięcie dowolnych ciągów we wszystkich powłokach podobnych do Bournea. Alternatywnie możesz umieścić kod awk w łańcuchu w podwójnym cudzysłowie:awk "{print \"'\" \$0 \"'\" }"
Odpowiedź
Uwaga t nie potrzebujesz do tego celu awk
.
Zamiast tego możesz użyć podstawowego narzędzia paste
:
< input paste -d """ /dev/null - /dev/null
Byłoby bardziej wydajne i miał mniej ograniczeń niż awk
-based lub sed
.
Odpowiedź
Kod awk musi być po prostu
{ print """ $0 """ }
Możesz umieścić to w pliku, więc nie musisz niczego cytować:
$ printf "a\nb\n" | awk -f quote.awk "a" "b"
Lub użyj ciąg znaków w podwójnym cudzysłowie i unikaj cudzysłowów i znaku dolara:
$ printf "a\nb\n" | awk "{ print \""\" \$0 \""\" }"
Lub w Bash / ksh / zsh użyj $"..."
forma cudzysłowów, która pozwala pominąć pojedynczy cudzysłów w środku:
$ printf "a\nb\n" | awk $"{ print "\"" $0 "\"" }"
Odpowiedź
możesz też użyć polecenia sed
.
<infile sed -E "s/^|$/"/g"
lub
<infile sed -E "s/.*/"&"/"
Komentarze
- Lub
sed -E "s/.*/'&'/" infile
. - @chepner tak, przeniosłem to do odpowiedzi 🙂
Odpowiedź
Jeden sposobem ujęcia łańcucha w pojedyncze cudzysłowy jest użycie polecenia printf gnu xargs:
< file xargs -d"\n" printf ""%s"\n"
Perl
perl -sple "$_="$q$_$q"" -- -q=\" file
Korzystanie z GNU sed:
sed -e "G;H;z;x;y/\n/"/" file