Załóżmy, że $file
trzymasz wartość nazwy pliku, powiedzmy Dr' A.tif
. W programowaniu bash, jak mogę uniknąć pojedynczego cudzysłowu i innych znaków specjalnych $file
bez usuwania znaku specjalnego?
Aktualizacja w dniu 9 lipca 2014 r
Na żądanie @Gilles następujący fragment kodu, który nie jest w stanie obsłużyć Dr' A.tif
:
files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]")
echo "${files}" > ${TEMP_FILE}
while read file
do
newfile=$(echo "${file}" | sed 's, ,\\ ,g') ## line 1
done < ${TEMP_FILE}
Po Próbowałem się na odpowiedź od @Patrick na line 1
, wydaje się pracować dla mnie. Ale jeśli mam taki plik Dr\^s A.tif
, printf
polecenie nie wydaje się pomocne, pokazuje mi Dr\^s\ A.tif
. Jeśli ręcznie wypróbuję to na konsoli:
printf "%q" "Dr\^s A.tif"
Będę miał ten wynik:
Dr\\\^s\ A.tif
Masz pomysł, jak sobie z tym poradzić?
Odpowiedzi:
Aby to zrobić, możesz użyć
printf
wbudowanego%q
. Na przykład:Z dokumentacji bash na
printf
:źródło
printf '%s' "foo"
. Najpierw musisz zrozumieć, jak parsowanie argumentów działa w powłoce. Zobacz gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 dzieje się przed # 6.printf
żadnych innych manipulacjiIt doesn't have a: ""
printf
. Problem polega na tym, że nie chcesz, aby powłoka analizowała łańcuch. Aby to zrobić, musisz przekazać swój wkład do powłoki w taki sposób, aby nawet nie próbowała go parsować. Jednym ze sposobów, aby to zrobić, jestread -r -p 'input: ' && printf '%q\n' "$REPLY"
podanie danych wejściowych po wyświetleniu monitu.printf
. Być może powinieneś zadać pytanie zamiast krytykować rozwiązanie, które nie ma nic wspólnego z twoim problemem.Próbować:-
lub
lub jeśli ciąg zawiera podwójny cudzysłów: -
Istnieją dobre samouczki na temat ucieczki i cytowania w sieci. Zacznij od tego .
źródło
W skrypcie nie trzeba uciekać żadnych nazw plików obsługiwanych przez użytkownika. Ucieczka jest konieczna tylko wtedy, gdy chcesz umieścić nazwę pliku jako literał w skrypcie lub przekazać kilka nazw plików jako pojedynczy strumień wejściowy do innego skryptu.
Skoro jesteś zapętlenie poprzez wyjście
find
, to jest jednym z najprostszych sposobów (!) Obsłużyć każdą możliwą ścieżkę :źródło
szybkie i (bardzo) brudne
źródło
Wiele z tych odpowiedzi, w tym najczęściej wybierane
printf "%q"
, nie będzie działać we wszystkich przypadkach bez dodatkowej manipulacji. Sugerowałbym następujące (przykład poniżej):cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn't contain lexemes: "" EOF
źródło