Kuinka paeta merkkijonon erikoismerkkejä?

Oletetaan, että $file, jolla on tiedostonimen arvo, sano Dr" A.tif. Kuinka voin paeta bash-ohjelmoinnissa yksittäisen lainauksen ja minkä tahansa muun $file -merkin poistamatta erikoismerkkiä?

Päivitys 9. heinäkuuta 2014

Kuten pyyntö käyttäjältä @Gilles , seuraava koodinpätkä, joka ei pysty käsittelemään 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} 

Kun olen kokeillut vastaus käyttäjältä @Patrick osoitteessa line 1, se näyttää toimivan minulle. Mutta jos minulla on tiedosto, kuten Dr\^s A.tif, printf -komento ei näytä olevan apua, se näyttää minulle Dr\^s\ A.tif. Jos yritän sitä manuaalisesti tällä tavalla:

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

Minulla on tämä lähtö:

Dr\\\^s\ A.tif

Onko sinulla ideoita tämän käsittelemiseksi?

Kommentit

  • mihin aiotko käyttää $ tiedostoa? vai määrittekö tämä ongelma merkkijonon erikoismerkillä $-tiedostoon?
  • Itse asiassa find-komento palauttaa minulle joukon tiedostoluetteloita. Ja sitten silmukan tämän tiedostoluettelon läpi $ -muuttujaan.
  • Sinulle ’ on annettu joitain oikeita vastauksia täällä, mutta ne eivät todennäköisesti ole vastauksia kysymys, jonka ’ todella kysyt. Täällä olevan kommenttisi perusteella epäilen vahvasti, että ’ olet väärällä radalla. Voimme ’ auttaa sinua paljon, koska et jatkuvasti näytä koodiasi. Suosittelen kuitenkin lukemaan Miksi komentosarjan komentosarjani tukahduttaa välilyönnin tai muita erikoismerkkejä? taustana. Näytä komentosarjasi ja selitä mitä haluat tehdä.

Vastaa

Sinä voi käyttää printf sisäänrakennettua %q -sovellusta tämän saavuttamiseksi. Esimerkiksi:

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

printf: n bash-ohjeista:

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) 

kommentit

  • Tämä ei toimi ’ t tietyissä tapauksissa kun sinun on säilytettävä lainausmerkit.
  • @ user3467349 se toimii hienosti lainausmerkeillä. Vedon

vedonlyöntiäsi ’ kokeillessani jotainprintf '%s' "foo". Sinun on ensin ymmärrettävä, kuinka argumenttien jäsentäminen toimii kuoressa. Katso

gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 ennen # 6.

  • Voisitko anna esimerkki tästä merkkijonosta, joka on painettu printf -toiminnolla eikä muita manipulaatioita It doesn't have a: ""
  • Asiaasi ei ole mitään tekemistä printf. Ongelmasi on, että et ’ et halua, että kuori jäsentää merkkijonosi. Tätä varten sinun on välitettävä syötteesi kuorelle tavalla, jossa se ei edes yritä jäsentää sitä ’. Yksi tapa tehdä tämä olisi read -r -p 'input: ' && printf '%q\n' "$REPLY", ja annat syötteen pyydettäessä.
  • Kuten minä ’ ve sanoin useita kertoja nyt. Tietämättömyys siitä, miten raakatiedot siirretään kuoreen, ei ole ’ t ongelma printf. Ehkä sinun pitäisi esittää kysymys pikemminkin kuin kritisoida ratkaisua, jolla ei ole mitään tekemistä ongelmasi kanssa.
  • Vastaa

    Kokeile: –

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

    tai

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

    tai jos merkkijono sisältää kaksinkertaisen lainaus: –

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

    Netissä on hyviä pakenemis- ja lainausohjeita. Aloita tällä .

    Vastaa

    Et halua ”Sinun ei tarvitse välttää kaikkia komentosarjassa käsittelemiäsi tiedostojen nimiä. Pakeneminen on välttämätöntä vain, jos haluat lisätä tiedostonimen komentosarjaan kirjaimena tai välittää useita tiedostonimiä yhtenä tulovirta toiseen komentosarjaan.

    Koska etsit silmukkaa find -lähdön läpi, tämä on yksi yksinkertaisimmista tavoista (!) käsitellä kaikkia mahdollisia polkuja :

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

    Vastaa

    nopea ja (erittäin) likainen

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

    vastaus

    Monet näistä vastauksista, mukaan lukien eniten äänestetyt vastaukset, jotka käyttävät printf "%q" eivät toimi kaikissa tapauksissa ilman ylimääräistä manipulointia.Ehdotan seuraavaa (esimerkki alla):

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

    Kommentit

    • Anteeksi n00b-kysymys, mutta voisitteko kertoa tarkemmin, kuinka käytät tätä todella merkkijonon merkkien välttämiseksi? Jos kopioin kirjoittamasi koodin päätelaitteeseeni, se vain tulostaa 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] tekstihakukysely ei ’ t sisältää leksemejä: ” ” … mitään ei voida välttää.
    • Että ’ kirjaimellisesti asia, kaikki erikoismerkit tulkitaan kirjaimellisiksi hahmoiksi niiden erityisen merkityksen vuoksi. Yritä sen sijaan nähdä kaiku ” yllä oleva merkkijono ” nähdäksesi eron.

    Vastaa

    Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *