awk print apostrof / single quote

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

Odpowiedź

Oto kilka sposobów:

  1. 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" 
  2. 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 jako awk -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 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *