Awk içinde tek bir alıntıdan nasıl kaçılır


111

Aşağıdakileri yapmak istiyorum

awk 'BEGIN {FS=" ";} {printf "'%s' ", $1}'

Ancak bu şekilde tek alıntıdan kaçmak işe yaramaz

awk 'BEGIN {FS=" ";} {printf "\'%s\' ", $1}'

Bu nasıl yapılır? Yardım için teşekkürler.


Bazı diller, iki tanesini arka arkaya koyarak alıntılardan kaçınabilir, belki bunu deneyebilirsiniz.
joshuahealy

Awk 'BEGIN {FS = "";} {printf "' '% s' '", $ 1}' denedim, ancak tek bir alıntı basılmadı.

Bu Sayfa , tek tırnaklı bir dizede tek bir alıntı eklemenin imkansız olduğunu söylüyor. Belki çift tırnağa çevirmen gerekecek.
joshuahealy

2
İmkansızdır, ancak iki bitişik tek tırnaklı kabuk dizgisi tek bir parametrede birbirine yapışır. Ve beyaz boşluk olmayan karakterlerle yapıştırılmış iki tek tırnaklı kabuk dizgisi de büyük bir glob'a yapıştırılır: 'abc'd'ef'is abcdef: literal plus dplus literal. dTırnak dışında olduğunu ve bunu yerine donunla \'yapmak 'abc'\''ef'için hangi değerlendirir abc'ef.
Kaz

Yanıtlar:


160

Belki de aradığınız şey:

awk 'BEGIN {FS=" ";} {printf "'\''%s'\'' ", $1}'

Yani, '\''siz açıklığı kapatın ', ardından 'ondan kaçarak bir literal yazdırın ve son olarak 'tekrar açın .


48
Awk ile ilgisi yok. 'Karakter açılış kapatan 'kabuk dize. Kabuk değişmez değeri bunun için ters eğik çizgi kaçışını desteklemez. Dizisi '\''o (bir kaçış kullanarak tek tırnak değişmezi, belirtir tırnak karakteri kapatır: hile yok edilir ve daha sonra tek tırnak değişmezleri dışında destekli) yeni tek tırnak değişmezi yeniden açılır. Tek bir teklif almak için bunu dört karakterli bir kaçış dizisi olarak düşünebilirsiniz. :)
Kaz

2
@Steve: Çok yararlı cevabınız için çok teşekkürler. Beni bir sürü baş ağrısından kurtardın!
John Slegers

4
@syntaxerror Çağırmak için bağımsız değişkenler hazırlarken kullandığınız alıntılar awk, tamamen komut satırları oluşturmak için kullandığınız komut yorumlayıcısına bağlıdır. '{printf $2}'Bir bazı argüman dönüştü alır execvesadece tek bir tırnak işareti olmadan boş sonlandırılmış C ip gibi bir sistem çağrısı veya benzeri. Awk alıntıları asla görmez ve sed de görmez. Sen aslında kullanım çift tırnak can, ancak çift tırnak içinde kabuk genişlemesini engellemez $2bunu edebi yapmak için bir ters eğik çizgi ile dolar işareti kaçmak zorunda: "{printf \$2}".
Kaz

4
@syntaxerror Özel olarak, satır içi bir awk betiğinden genellikle tek tırnak ile kaçılır, çünkü awk sözdizimi genellikle kabuğa özel, çift tırnaklı dizgi sabitleri ve dolar işaretleriyle gösterilen numaralı alanlar gibi, kabuğa özel sözcük öğeleri içerir. Bir sed düzenli ifadesi (veya her neyse) kabuk sözdizimi içeriyorsa, ayrıca dikkatli olmalısınız. sed -e "s/$FOO/$BAR/"amaç hazır metni $FOOile değiştirmekse çalışmayacaktır $BAR. En kolay yol bu olurdu sed -e 's/$FOO/$BAR/.
Kaz

1
@syntaxerror Awk programlarını çift tırnak içine alırsanız, birçok kaçışla karşılaşırsınız, örneğin awk "{ print \"abc\", \$1 }". Awk programında her çift tırnak göründüğünde, kabuk teklifini kapatmaması için kaçılması gerekir. Ve şunu karşılaştırın: awk '{print "\\"}'(ters eğik çizgi yazdırın) ile çift tırnaklarla ne yapılması gerektiğini karşılaştırın:, awk "BEGIN {print \"\\\\\" }"Phew! Her iki tırnaktan da kaçınılmalıdır ve her iki ters eğik çizgi. Kabuk dönüşür \\ , \ bu yüzden \\\\ kodlamamız gerekir \\ .
Kaz

76

Tek bir alıntı kullanılarak temsil edilir \x27

Gibi

awk 'BEGIN {FS=" ";} {printf "\x27%s\x27 ", $1}'

Kaynak


16
+1, ancak eklenmesi gerekiyor: \x27bir uzantıdır; POSIX Awk yalnızca tanır \047. ( \47arkasından sekizlik bir rakam
gelmezse de tamamdır

1
Sonrasında başka bir numara varsa \ x27 nasıl bitirirsin?
Jason Axelson

1
Jason, iki değişmez dizeyi birleştirdin: "AAA \ x27" "1". Ya da sadece sekizlik kullanırsınız.
hemflit

9
Her zaman \047onaltılık ( \x27) değil , kaçış kodlarını kullanın - bkz. Awk.freeshell.org/PrintASingleQuote .
Ed Morton

35

Diğer bir seçenek de tek alıntıyı awk değişkeni olarak iletmektir :

awk -v q=\' 'BEGIN {FS=" ";} {printf "%s%s%s ", q, $1, q}'

Dize birleştirme ile daha basit örnek:

# Prints 'test me', *including* the single quotes.
$ awk -v q=\' '{print q $0 q }' <<<'test me'
'test me'

5
Bu, özellikle çok sayıda alıntı kullanmanız gerekiyorsa, açık ve özdür.
Peter Gluck

18
awk 'BEGIN {FS=" "} {printf "\047%s\047 ", $1}'

1
\047Tek tırnak karakterinin sekizlik kaçış dizisi olduğunu hatırladığım sürece , bu alternatifi en okunaklı buluyorum.
Anthony Geoghegan

4

Küçük komut dosyaları için, onu okunabilir hale getirmenin isteğe bağlı bir yolu, aşağıdaki gibi bir değişken kullanmaktır:

awk -v fmt="'%s'\n" '{printf fmt, $1}'

Çıktıdaki tek tırnak karakterini birçok kez üretmek zorunda kaldığım ve \ 047'nin onu tamamen okunamaz hale getirdiği bir durumda bunu uygun buldum

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.