Hoe ontsnap ik aan speciale tekens in een string?

Ervan uitgaande dat $file een waarde van een bestandsnaam bevat, zeg dan Dr" A.tif. Hoe kan ik bij bash-programmering ontsnappen aan een enkel aanhalingsteken en elk ander speciaal teken van de $file zonder het speciale teken te verwijderen?

Update op 9 juli 2014

Als verzoek van @Gilles , volgend codefragment dat Dr" A.tif niet “aankan:

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} 

Nadat ik de antwoord van @Patrick op line 1, het lijkt voor mij te werken. Maar als ik een bestand heb zoals Dr\^s A.tif, printf commando lijkt niet te helpen, het laat me Dr\^s\ A.tif zien. Als ik het handmatig op de console probeer, zoals dit:

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

zal ik deze uitvoer hebben:

Dr\\\^s\ A.tif

Enig idee hoe hiermee om te gaan?

Reacties

  • in wat context verwacht u $ file te gebruiken? of is dit een probleem bij het toewijzen van de string met het speciale teken aan $ file?
  • Eigenlijk geeft het find commando me een array van bestandenlijst terug. En dan loop ik door deze bestandslijst naar $ file variabele.
  • U ' hebt hier enkele goede antwoorden gekregen, maar dit zijn waarschijnlijk niet de antwoorden op de vraag die je ' echt stelt. Op basis van uw opmerking hier, vermoed ik sterk dat u ' op het verkeerde spoor zit. We kunnen ' je niet veel helpen omdat je steeds je code niet laat zien. Ik raad u echter aan om te lezen. Waarom verslikt mijn shellscript in witruimte of andere speciale tekens? als achtergrond. Laat uw script zien en leg uit wat u wilt doen.

Antwoord

Jij kan de printf gebruiken die is ingebouwd met %q om dit te bereiken. Bijvoorbeeld:

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

Van de bash-documentatie op 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) 

Reacties

  • Dit werkt niet ' t met bepaalde gevallen .eg wanneer u dubbele aanhalingstekens moet behouden.
  • @ user3467349 werkt het prima met aanhalingstekens. Ik ' m wedden dat je ' iets als printf '%s' "foo" probeert. U moet eerst begrijpen hoe argument-parsing in de shell werkt. Zie gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 gebeurt vóór # 6.
  • Zou je geef een voorbeeld van deze string afgedrukt met printf en geen andere manipulaties It doesn't have a: ""
  • Uw probleem heeft niets te maken met printf. Uw probleem is dat u niet ' wilt dat de shell uw string ontleedt. Om dat te doen, moet je je invoer naar de shell sturen op een manier waarop het niet ' zelfs probeert het te ontleden. Een manier om dit te doen is read -r -p 'input: ' && printf '%q\n' "$REPLY", en voer de invoer in wanneer daarom wordt gevraagd.
  • Zoals ik ' heb gezegd meerdere keren nu. Niet weten hoe onbewerkte gegevens naar de shell moeten worden gestuurd, is n ' t een probleem met printf. Misschien moet u een vraag stellen in plaats van kritiek uit te oefenen op een oplossing die niets met uw probleem te maken heeft.

Antwoord

Probeer: –

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

of

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

of als de string een dubbele bevat quote: –

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

Er zijn goede tutorials over ontsnappen en citeren op het net. Begin met deze .

Antwoord

Je hoeft niet “U hoeft de bestandsnamen die u in een script verwerkt niet te escapen. Ontsnappen is alleen nodig als u een bestandsnaam als een letterlijke in een script wilt plaatsen, of als u meerdere bestandsnamen als een enkele wilt doorgeven invoerstroom naar een ander script.

Aangezien u “de uitvoer van find opnieuw doorloopt, dit is een van de eenvoudigste manieren (!) om elk mogelijk pad af te handelen :

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" {} +) 

Antwoord

snel en (erg) vies

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

Antwoord

Veel van deze antwoorden, inclusief de meest gestemde met printf "%q" zullen werken niet in alle gevallen zonder extra manipulatie.Ik zou het volgende willen voorstellen (voorbeeld hieronder):

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

Reacties

  • Excuseer de n00b-vraag, maar kun je uitleggen hoe je dit daadwerkelijk zou gebruiken om aan tekens in een string te ontsnappen? Als ik de code die u naar mijn terminal schrijft kopieer, wordt de app 2015-11-07T03: 34: 41Z [postgres.0000]: [TAG] tekstzoekopdracht niet ' t afgedrukt bevatten lexemes: " " … niets wordt ontsnapt.
  • Dat ' is letterlijk het punt, alle speciale tekens worden geïnterpreteerd als letterlijke tekens, niet vanwege hun speciale betekenis. Probeer in plaats daarvan echo " de bovenstaande string " om het verschil te zien.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *