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 på 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 manipulasjonerIt 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æreread -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.