Hvordan undgår man specialtegn i en streng?

Forudsat at $file har en værdi af et filnavn, skal du sige Dr" A.tif. Hvordan kunne jeg i bash-programmering undslippe et enkelt citat og ethvert andet specialtegn i $file uden at fjerne specialtegnet?

Opdatering den 9. juli 2014

Som anmodning fra @Gilles , følgende kodestykke, der 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} 

Efter at jeg har prøvet svar fra @Patrick line 1, ser det ud til at fungere for mig. Men hvis jeg har en fil som Dr\^s A.tif, printf kommando ser ikke ud til at hjælpe, det viser mig Dr\^s\ A.tif. Hvis jeg manuelt prøver det på konsollen sådan:

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

får jeg denne output:

Dr\\\^s\ A.tif

Har du nogen idé om, hvordan du håndterer dette?

Kommentarer

  • i hvad kontekst forventer du at bruge $ file? eller er dette problem at tildele strengen med specialtegnet til $-filen?
  • Faktisk giver kommandoen find mig en række fillister. Og så løber jeg gennem denne filliste til $ -filvariablen.
  • Du ' har fået nogle korrekte svar her, men de er sandsynligvis ikke svarene på spørgsmål, som du ' virkelig spørger. Fra din kommentar her mistænker jeg stærkt, at du ' er på det forkerte spor. Vi kan ' ikke hjælpe dig meget, fordi du hele tiden ikke viser din kode. Jeg anbefaler dog, at du læser Hvorfor kvæler mit shell-script i hvidt mellemrum eller andre specialtegn? som baggrund. Vis dit script og forklar, hvad du vil gøre.

Svar

Dig kan bruge printf indbygget med %q til at opnå 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-dokumentationen 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 sager .eg når du har brug for at bevare dobbelt citater.
  • @ user3467349 det fungerer fint med tilbud. Jeg ' satser på dig ' prøver noget i retning af printf '%s' "foo". Du skal først forstå, hvordan argumentparsing fungerer i skallen. Se gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 sker før nr. 6.
  • Kunne du se give et eksempel på denne streng trykt med printf og ingen andre manipulationer It doesn't have a: ""
  • Dit problem har intet at gøre med printf. Dit problem er, at du ikke ' ikke ønsker, at skallen skal analysere din streng. For at gøre det skal du sende dit input til skallen på en måde, hvor den ikke ' ikke engang prøver at analysere den. En måde at gøre dette på ville være read -r -p 'input: ' && printf '%q\n' "$REPLY" og give input, når du bliver bedt om det.
  • Som jeg ' har sagt flere gange nu. Ikke at vide, hvordan man overfører rådata til skallen, er ikke ' t et problem med printf. Måske skal du stille et spørgsmål i stedet for at kritisere en løsning, der ikke har noget med dit problem at gøre.

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 indeholder en dobbelt quote: –

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

Der er gode vejledninger i at flygte og citere på nettet. Start med denne .

Svar

Du don “behøver ikke at slippe for alle filnavne, du håndterer i et script. Undslippe er kun nødvendigt, hvis du vil placere et filnavn som et bogstaveligt i et script eller at videregive flere filnavne som en enkelt input stream til et andet script.

Da du løber gennem output fra find, dette er en af de enkleste måder (!) til håndtere alle mulige stier :

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

hurtig og (meget) snavset

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

Svar

Mange af disse svar inklusive den topstemme, der bruger printf "%q" vil fungerer ikke i alle tilfælde uden yderligere manipulation.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

  • Undskyld n00b-spørgsmålet, men kan du uddybe, hvordan du rent faktisk ville bruge dette til at undslippe tegn i en streng? Hvis jeg kopierer den kode, du skriver til min terminal, udskrives den bare 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] tekst-søgeforespørgsel betyder ikke ' t indeholder lexemes: " " … intet er undsluppet.
  • At ' er bogstaveligt talt pointen, alle specialtegn fortolkes som bogstavelige tegn ikke for deres særlige betydning. Prøv at echo " ovenstående streng " i stedet for at se forskellen.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *