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 manipulatiesIt 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 isread -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.