Hvordan unnslippe spesialtegn i en streng?

Forutsatt at $file holder en verdi av et filnavn, si Dr" A.tif. I bash-programmering, hvordan kunne jeg unnslippe enkelt sitat og andre spesielle tegn i $file uten å fjerne spesialtegnet?

Oppdatering 9. juli 2014

Som forespørsel fra @Gilles , følgende kodebit som ikke kan håndtere 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} 

Etter at jeg har prøvd ut svar fra @Patrick line 1, ser det ut til å fungere for meg. Men hvis jeg har en fil som Dr\^s A.tif, printf -kommandoen ser ikke ut til å hjelpe, den viser meg Dr\^s\ A.tif. Hvis jeg manuelt prøver det på konsollen slik:

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

får jeg denne utgangen:

Dr\\\^s\ A.tif

Har du noen ide om hvordan du skal håndtere dette?

Kommentarer

  • i hva kontekst forventer du å bruke $ file? eller er dette problemet å tilordne strengen med spesialtegnet til $ file?
  • Egentlig finner kommandoen find meg en rekke fillister. Og så løper jeg gjennom denne fillisten til $ file-variabel.
  • Du ' har fått noen riktige svar her, men de er sannsynligvis ikke svarene på spørsmål som du ' virkelig spør. Fra din kommentar her mistenker jeg sterkt at du ' er på feil spor. Vi kan ' ikke hjelpe deg mye fordi du stadig ikke viser koden din. Jeg anbefaler imidlertid at du leser Hvorfor kveles skallskriptet mitt på hvitt mellomrom eller andre spesialtegn? som bakgrunn. Vis skriptet ditt og forklar hva du vil gjøre.

Svar

Du kan bruke printf innebygd med %q for å oppnå dette. For eksempel:

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

Fra bash-dokumentasjonen 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

  • Dette fungerer ikke ' med visse tilfeller .eg når du trenger å bevare dobbelt anførselstegn.
  • @ user3467349 fungerer det helt fint med anførselstegn. Jeg ' satser på deg ' prøver noe sånt som printf '%s' "foo". Du må forstå hvordan argumentparsering fungerer i skallet først. Se gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 skjer før nr. 6.
  • Kan du gi et eksempel på denne strengen trykt med printf og ingen andre manipulasjoner It doesn't have a: ""
  • Problemet ditt har ingenting å gjøre med printf. Problemet ditt er at du ikke vil ' ikke vil at skallet skal analysere strengen din. For å gjøre det, må du sende innspillene til skallet på en måte der det ikke ' ikke engang prøver å analysere det. En måte å gjøre dette på ville være read -r -p 'input: ' && printf '%q\n' "$REPLY", og gi innspill når du blir bedt om det.
  • Som jeg ' har sagt flere ganger nå. Å ikke vite hvordan du skal overføre rådata til skallet er ikke ' t et problem med printf. Kanskje du bør stille et spørsmål i stedet for å kritisere en løsning som ikke har noe å gjøre med problemet ditt.

Svar

Prøv: –

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

eller

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

eller hvis strengen inneholder en dobbel sitat: –

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

Det er gode veiledninger om å rømme og sitere på nettet. Start med denne .

Svar

Du don «t trenger å unnslippe filnavnene du håndterer i et skript. Å rømme er bare nødvendig hvis du vil sette et filnavn som en bokstavelig i et skript, eller å sende flere filnavn som en enkelt inngangsstrøm til et annet skript.

Siden du går gjennom utdata fra find, dette er en av de enkleste måtene (!) å håndtere alle mulige baner :

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

raskt og (veldig) skittent

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

Svar

Mange av disse svarene inkludert den toppstemte som bruker printf "%q" vil fungerer ikke i alle tilfeller uten ytterligere manipulasjon.Jeg vil foreslå følgende (eksempel nedenfor):

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

Kommentarer

  • Unnskyld n00b-spørsmålet, men kan du utdype hvordan du faktisk vil bruke dette til å unnslippe tegn i en streng? Hvis jeg kopierer koden du skriver inn i terminalen min, skrives den bare ut 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] tekstsøk-spørring betyr ikke ' t inneholder lexemer: " " … ingenting unnslippes.
  • At ' er bokstavelig talt poenget, alle spesialtegnene tolkes som bokstavelige tegn, ikke for deres spesielle betydning. Prøv å ekko " strengen ovenfor " i stedet for å se forskjellen.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *