Hur kan man undkomma specialtecken i en sträng?

Antag att $file innehar ett värde på ett filnamn, säg Dr" A.tif. Hur kunde jag undvika enstaka citat och andra specialtecken i $file i bash-programmering utan att ta bort specialtecknet?

Uppdatering den 9 juli 2014

Som begäran från @Gilles , följande kodavsnitt som inte kan hantera 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} 

När jag har testat svar från @Patrick line 1 verkar det fungera för mig. Men om jag har en fil som Dr\^s A.tif, printf -kommandot verkar inte hjälpa, det visar mig Dr\^s\ A.tif. Om jag försöker manuellt på konsolen så här:

printf "%q" "Dr\^s A.tif"

får jag den här utgången:

Dr\\\^s\ A.tif

Någon idé om hur man hanterar detta?

Kommentarer

  • i vad sammanhang förväntar du dig att använda $ file? eller är det här problemet att tilldela strängen med specialtecknet till $-filen?
  • Egentligen ger kommandot find mig en matris med fillista. Och sedan slingrar jag igenom denna fillista till $ -filvariabel.
  • Du ' har fått några korrekta svar här, men de är förmodligen inte svaren på fråga som du ' verkligen frågar. Från din kommentar här misstänker jag starkt att du ' befinner dig på fel spår. Vi kan ' inte hjälpa dig mycket eftersom du fortsätter att inte visa din kod. Jag rekommenderar dock att du läser Varför kväver mitt skalskript på blanksteg eller andra specialtecken? som bakgrund. Visa ditt skript och förklara vad du vill göra.

Svara

Du kan använda printf inbyggd med %q för att uppnå detta. Till exempel:

$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\` 

Från basdokumentationen på printf:

In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3) 

Kommentarer

  • Detta fungerar inte ' med vissa fall .eg när du behöver bevara dubbla citat.
  • @ user3467349 fungerar det bra med citat. Jag ' satsar på dig ' försöker något som printf '%s' "foo". Du måste först förstå hur argumentparsning fungerar i skalet. Se gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 händer före # 6.
  • Kan du ge ett exempel på denna sträng tryckt med printf och inga andra manipulationer It doesn't have a: ""
  • Ditt problem har inget att göra med printf. Problemet är att du inte ' inte vill att skalet ska analysera din sträng. För att göra det måste du skicka din inmatning till skalet på ett sätt där det inte ens ' försöker analysera det. Ett sätt att göra detta skulle vara read -r -p 'input: ' && printf '%q\n' "$REPLY" och ge inmatningen när du uppmanas till det.
  • Som jag ' har sagt flera gånger nu. Att inte veta hur man skickar rådata till skalet är inte ' t ett problem med printf. Du kanske borde ställa en fråga snarare än att kritisera en lösning som inte har något att göra med ditt problem.

Svar

Försök: –

file=Dr\"\ A.tif echo $file Dr" A.tif 

eller

file="Dr" A.tif" echo $file Dr" A.tif 

eller om strängen innehåller en dubbel citat: –

file="Dr" A.tif" echo $file Dr" A.tif 

Det finns bra handledning om hur man flyr och citerar på nätet. Börja med den här .

Svar

Du don ”t behöver undkomma alla filnamn du hanterar i ett skript. Flykt är endast nödvändigt om du vill lägga in ett filnamn som bokstavligt i ett skript, eller att skicka flera filnamn som en enda mata in ström till ett annat skript.

Eftersom du går igenom utdata från find, detta är ett av de enklaste sätten (!) att hantera alla möjliga sökvägar :

while IFS= read -r -d "" do file_namex="$(basename -- "$REPLY"; echo x)" file_name="${file_namex%$"\nx"}" do_something -- "$file_name" done <(find "$some_path" -exec printf "%s\0" {} +) 

Svar

snabbt och (mycket) smutsigt

find . | sed "s/^/"/" | sed "s/$/"/" 

Svar

Många av dessa svar inklusive den högst röstade med printf "%q" kommer fungerar inte i alla fall utan ytterligare manipulation.Jag föreslår följande (exempel nedan):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF

Kommentarer

  • Ursäkta n00b-frågan men kan du utarbeta hur du faktiskt skulle använda detta för att komma undan tecken i en sträng? Om jag kopierar koden som du skriver till min terminal skrivs den bara ut 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] text-sökfråga inte ' t innehålla lexemes: " " … ingenting undviks.
  • Att ' är bokstavligen poängen, alla specialtecken tolkas som bokstäver inte för deras speciella betydelse. Försök att echo " ovanstående sträng " istället för att se skillnaden.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *