Antag att $file
innehar ett värde på ett filnamn, säg Dr" A.tif
. Hur kunde jag undvika enstaka citat och andra specialtecken i $file
i bash-programmering utan att ta bort specialtecknet?
Uppdatering den 9 juli 2014
Som begäran från @Gilles , följande kodavsnitt som inte kan hantera 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}
När jag har testat svar från @Patrick på line 1
verkar det fungera för mig. Men om jag har en fil som Dr\^s A.tif
, printf
-kommandot verkar inte hjälpa, det visar mig Dr\^s\ A.tif
. Om jag försöker manuellt på konsolen så här:
printf "%q" "Dr\^s A.tif"
får jag den här utgången:
Dr\\\^s\ A.tif
Någon idé om hur man hanterar detta?
Kommentarer
- i vad sammanhang förväntar du dig att använda $ file? eller är det här problemet att tilldela strängen med specialtecknet till $-filen?
- Egentligen ger kommandot find mig en matris med fillista. Och sedan slingrar jag igenom denna fillista till $ -filvariabel.
- Du ' har fått några korrekta svar här, men de är förmodligen inte svaren på fråga som du ' verkligen frågar. Från din kommentar här misstänker jag starkt att du ' befinner dig på fel spår. Vi kan ' inte hjälpa dig mycket eftersom du fortsätter att inte visa din kod. Jag rekommenderar dock att du läser Varför kväver mitt skalskript på blanksteg eller andra specialtecken? som bakgrund. Visa ditt skript och förklara vad du vill göra.
Svara
Du kan använda printf
inbyggd med %q
för att uppnå detta. Till exempel:
$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\`
Från basdokumentationen 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
- Detta fungerar inte ' med vissa fall .eg när du behöver bevara dubbla citat.
- @ user3467349 fungerar det bra med citat. Jag ' satsar på dig ' försöker något som
printf '%s' "foo"
. Du måste först förstå hur argumentparsning fungerar i skalet. Se gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 händer före # 6. - Kan du ge ett exempel på denna sträng tryckt med
printf
och inga andra manipulationerIt doesn't have a: ""
- Ditt problem har inget att göra med
printf
. Problemet är att du inte ' inte vill att skalet ska analysera din sträng. För att göra det måste du skicka din inmatning till skalet på ett sätt där det inte ens ' försöker analysera det. Ett sätt att göra detta skulle vararead -r -p 'input: ' && printf '%q\n' "$REPLY"
och ge inmatningen när du uppmanas till det. - Som jag ' har sagt flera gånger nu. Att inte veta hur man skickar rådata till skalet är inte ' t ett problem med
printf
. Du kanske borde ställa en fråga snarare än att kritisera en lösning som inte har något att göra med ditt problem.
Svar
Försök: –
file=Dr\"\ A.tif echo $file Dr" A.tif
eller
file="Dr" A.tif" echo $file Dr" A.tif
eller om strängen innehåller en dubbel citat: –
file="Dr" A.tif" echo $file Dr" A.tif
Det finns bra handledning om hur man flyr och citerar på nätet. Börja med den här .
Svar
Du don ”t behöver undkomma alla filnamn du hanterar i ett skript. Flykt är endast nödvändigt om du vill lägga in ett filnamn som bokstavligt i ett skript, eller att skicka flera filnamn som en enda mata in ström till ett annat skript.
Eftersom du går igenom utdata från find
, detta är ett av de enklaste sätten (!) att hantera alla möjliga sökvägar :
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
snabbt och (mycket) smutsigt
find . | sed "s/^/"/" | sed "s/$/"/"
Svar
Många av dessa svar inklusive den högst röstade med printf "%q"
kommer fungerar inte i alla fall utan ytterligare manipulation.Jag föreslår följande (exempel nedan):
cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF
Kommentarer
- Ursäkta n00b-frågan men kan du utarbeta hur du faktiskt skulle använda detta för att komma undan tecken i en sträng? Om jag kopierar koden som du skriver till min terminal skrivs den bara ut 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] text-sökfråga inte ' t innehålla lexemes: " " … ingenting undviks.
- Att ' är bokstavligen poängen, alla specialtecken tolkas som bokstäver inte för deras speciella betydelse. Försök att echo " ovanstående sträng " istället för att se skillnaden.