2012-08-15 10 views
38

muszę przekazać ciąg do programu jako argument z Bash CLI, npW jaki sposób wiodący znak dolara wpływa na pojedyncze cudzysłowy w Bash?

program "don't do this" 

Łańcuch może zawierać dowolną postać jak '$', '\' itp i nie chcę, aby cokolwiek Bash modyfikacja. Więc myślę o używaniu pojedynczych cudzysłowów.

Jednak następujące nie działa:

program 'don\'t do this'   //escape doesn't work in single quote 

Podczas dwóch następujących prac:

program $'dont\'t do this'   //seems fine, but any other side effects? 
program 'dont'\''do this'   //breaking into 3 parts 

Pierwsze podejście wydaje się lepszy w tym, że nabywa mniej pre modyfikacji (umieścić symbol dolara z przodu i zamień każdy \ na \\), ale nie wiem, co jeszcze może zrobić DOLLAR SIGN.

ja naprawdę google to, ale nie mogę znaleźć to, czego potrzebuję ...

+4

Aby lepiej zrozumieć przykład '$ '...'', spójrz na pierwszy akapit [strony informującej o bash] (http://www.gnu.org/software/bash /manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting) – suvayu

+0

Dziękujemy za zamieszczenie tego pytania. Kluczowe znaczenie ma zrozumienie, jak wyrównywać rekordy rozdzielane tabulatorami (np. 'Cat myData.tsv | column -t -s $ '\ t'') –

Odpowiedz

48

Powoduje to sekwencje należy interpretować.

$ echo $'Name\tAge\nBob\t24\nMary\t36' 
Name Age 
Bob  24 
Mary 36 

(I SO obsługuje kart w głupkowaty sposób, aby spróbować tego w domu)

+0

+1 dobry połów.Zgaduję, że tak się dzieje, ponieważ nazwy zmiennych są rozszerzone? –

+0

Nie, dzieje się tak, ponieważ jest to zdefiniowane zachowanie dla '$ '...''. –

+0

To jest dokładnie to, czego potrzebuję, jeśli to wszystko $ ''! – user1206899

18

Korzystanie $ jako przedrostek mówi bash, by spróbować znaleźć zmienną o tej nazwie. $' to specjalna składnia (fully explained here), która umożliwia przetwarzanie ciągów ANSI-C. W tym przypadku pojedynczy znacznik nie jest "przyjmuj wartości dosłownej do następnego pojedynczego tiku". Powinien być całkiem bezpieczny w użyciu. Wady są tylko BASH i dość rzadkie, więc wiele osób będzie się zastanawiać, co to znaczy.

Lepszym sposobem jest użycie pojedynczych cudzysłowów. Jeśli potrzebujesz pojedynczego cudzysłowu w ciągu znaków, musisz go zamienić na '\''. To kończy poprzedni pojedynczy cytowany łańcuch, dodaje pojedynczy cudzysłów (\'), a następnie rozpoczyna nowy pojedynczy cytowany ciąg. Ta składnia działa z każdym potomkiem Bourne shell, jest to dość łatwe do zrozumienia, a większość ludzi szybko rozpoznaje wzór.

Alternatywą jest replase każdego pojedynczego tiku z '"'"', co tłumaczy się na "zakończyć bieżący pojedynczy cudzysłowy ciąg, dopisać podwójny ciąg znaków, który zawiera tylko jeden znacznik, wznowienie pojedynczego cudzysłowu ciąg". Pozwala to uniknąć charakteru ucieczki i wygląda ładnie symetrycznie. Działa również na odwrót, jeśli potrzebujesz podwójnego cudzysłowu w ciągu cudzysłowów: "'"'".

+0

Tak, to jest poprawna metoda – user1206899

+2

Powszechne jest również zobaczenie '' "'"'. np. ''pies' '' '' s ogon'' –

+0

$ 'SHELL' i $ 'LANG' nie * nie *" zawiedzie ". Znak dolara w $ "ma inną funkcję. Powiedziałbym, że "\" jest * jeden * poprawny sposób. – jox

-1

Nie znajdziesz szybsze lub bardziej skuteczny sposób niż:

eval RESULT=\$\'$STRING\' 

Z jednej strony, jest to jedna z tych rzeczy, które eval jest tam, i uniknąć szalony koszt rozwidlone podproces w każdym miejscu, jak sugerują poprzednie odpowiedzi. Twój przykład:

$ foo='\u25b6' 
$ eval bar=\$\'$foo\' 
$ echo "$bar" 
▶ 
+0

To jest niezrozumienie, co oznacza składnia w Bash. '$ '...'' to ciąg w stylu C (http://www.gnu.org/software/bash/manual/bash.html#ANSI_002dC-Quoting), który stosuje się do różnych reguł cytowania niż zwykłe ciągi, zgodnie z innymi odpowiedziami na tej stronie. – tripleee