Jak mogę uniknąć podwójnych cudzysłowów w podwójnym ciągu w Bash?
Na przykład w moim skrypcie powłoki
#!/bin/bash
dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES"
Nie mogę uzyskać ENCLOSED BY '\"'
podwójnego cytatu, aby poprawnie uciec. Nie mogę używać pojedynczych cudzysłowów dla mojej zmiennej, ponieważ chcę używać zmiennej $dbtable
.
$dbtable
, istnieje ryzyko. Byłoby to jednak bardzo rzadkie, ponieważ użytkownicy końcowi zazwyczaj nie używają SSH do komputera w celu załadowania swoich danych.Odpowiedzi:
Użyj ukośnika odwrotnego:
źródło
x=ls; if [ -f "$(which "\""$x"\"")" ]; then echo exists; else echo broken; fi;
daje uszkodzony podczas... [ -f "$(which $x)" ]; ...
lub... [ -f $(which "$x") ]; ...
praca dobrze. Problemy pojawiałyby się, gdy którykolwiek$x
lub wynik$(which "$x")
dawałby coś ze spacją lub innym znakiem specjalnym. Obejście polega na użyciu zmiennej do przechowywania wynikuwhich
, ale czy bash naprawdę nie jest w stanie uciec od cytatu, czy robię coś źle?grep -oh "\"\""$counter"\""\w*"
jako części składni bash, gdzie in$counter
jest zmienną. nie podoba mi się żadna myślProsty przykład ucieczki cytatów w powłoce:
Odbywa się to poprzez ukończenie już otwartej (
'
), umieszczenie ucieczki (\'
), a następnie otwarcie kolejnej ('
).Alternatywnie:
Odbywa się to poprzez ukończenie już otwartego jednego (
'
), umieszczenie cytatu w innym cytacie ("'"
), a następnie otwarcie kolejnego ('
).Więcej przykładów: unikanie pojedynczych cudzysłowów w ciągach pojedynczych cudzysłowów
źródło
echo "abc\"abc"
wystarczy, aby uzyskaćabc"abc
jak w odpowiedzi Piotra.Nie wiem, dlaczego ten stary problem pojawił się dzisiaj na listach oznaczonych Bash, ale na wszelki wypadek dla przyszłych badaczy, pamiętaj, że możesz uniknąć ucieczki, używając kodów ASCII znaków, które musisz echo.
Przykład:
\x22
jest kodem ASCII (szesnastkowym) dla podwójnych cudzysłowów i\x27
pojedynczych cudzysłowów. Podobnie możesz powtórzyć dowolny znak.Przypuszczam, że jeśli spróbujemy powtórzyć powyższy ciąg za pomocą ukośników odwrotnych, będziemy potrzebować niechlujnego echa z dwoma odwróconymi ukośnikami ...
W przypadku przypisania zmiennych jest to odpowiednik:
Jeśli zmienna jest już ustawiona przez inny program, nadal możesz stosować podwójne / pojedyncze cudzysłowy za pomocą sed lub podobnych narzędzi.
Przykład:
źródło
echo 'export PS1='\[\033[00;31m\]${?##0}$([ $? -ne 0 ] && echo \x22 \x22)\[\033[00;32m\]\u\[\033[00m\]@\[\033[00;36m\]\h\[\033[00m\][\[\033[01;33m\]\d \t\[\033[00m\]] \[\033[01;34m\]\w\n\[\033[00m\]$( [ ${EUID} -ne 0 ] && echo \x22$\x22 || echo \x22#\x22 ) '' >> ~/.profile
Bash pozwala ci umieszczać łańcuchy obok siebie, a po prostu zostaną sklejone.
Więc to:
produkuje
Sztuczka polega na przełączaniu między ciągami pojedynczymi i podwójnymi w razie potrzeby. Niestety szybko robi się bardzo bałagan. Na przykład:
produkuje
W twoim przykładzie zrobiłbym coś takiego:
co daje następujące dane wyjściowe:
Trudno zobaczyć, co się tutaj dzieje, ale mogę to opatrzyć adnotacjami, używając cytatów Unicode. Poniższe nie działa w bash - to tylko dla ilustracji:
dbload=
„load data local infile "
” „'gfpoint.csv'
” „" into
„table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '
”"
„' LINES
„”TERMINATED BY "
„”'\n'
„”" IGNORE 1 LINES
”Cytaty takie jak „” ”powyżej zostaną zinterpretowane przez bash. Cytaty jak
" '
zakończą się w wynikowej zmiennej.Jeśli podam to samo traktowanie we wcześniejszym przykładzie, wygląda to tak:
$ echo
„I like to use
”„
"double quotes"
”„
sometimes
”źródło
Sprawdź printf ...
Bez użycia printf
Wyjście: powiedz „cześć”
Korzystanie z printf
Wyjście: powiedz „cześć”
źródło
printf
wymyka się więcej znaków, jak również, takie jak'
,(
i)
printf %q
generuje ciągi gotoweeval
, nie sformatowane dlaecho -e
.printf
z bezużytecznego wykorzystaniaecho
. Oba twoje przykłady mają zepsute cytaty. Poprawną poprawką jest podwójne cytowanie zmiennej.Zapisz znak podwójnego cudzysłowu jako zmienną:
Wynik:
źródło
Skorzystaj z $ „string”.
W tym przykładzie byłoby to
Uwaga (od strony man ):
źródło
Dodaj
"\"
przed podwójnym cytatem, aby go uniknąć, zamiast\
źródło
csh
odpowiedź nabash
pytanie? Oba są całkowicie różne i niezgodne.