Kuinka poistaa tiedostotunniste bash-tiedostoluettelosta

Yritän poistaa tiedostotunnisteen luettelosta tiedostoista, jotka olen luonut seuraavalla bash-komentosarja:

 #!/bin/bash file_list=$(find . -type f) #assuming that the files are stored in the same directory trimmed_file_list=$(printf "%s\n" "${file_list[@]%.*}") printf "%s\n" "${trimmed_file_list[@]}" 

Tämä laajennus leikkaa laajennuksen pois luettelon viimeisestä merkinnästä, mutta ei mitään aikaisemmista.

Haluan esimerkiksi seuraavan luettelon:

 file1.pdf file2.pdf file3.png 

Tulee

 file1 file2 file3 

Mutta saan sen sijaan:

 file1.pdf file2.pdf file3 

En halua tehdä tätä silmukassa, haluan käyttää parametrilaajennusta. Haluan välttää leikkaamista, koska haluan koskaan poistaa vain tiedoston viimeisen laajennuksen.

Parametrilaajennuksessa on melko paljon aiheita, ja näyttää siltä, että bash saattaa tukehtua find” käyttää uusia rivejä … En todellakaan ole varma. Jos jokin jo olemassa olevista aiheista selittää tämän ongelman, en ymmärrä täysin mitä tapahtuu.

Näennäisiä aiheita liittyvät, mutta älä näytä ratkaisevan ongelmaa:

Kommentit

  • Otsikossa mainitaan taulukot, mutta koodissasi ei ole taulukkoa.
  • @Kusalananda Kiitos! Olen ' ymmärtänyt sen kysymisen jälkeen. Opi edelleen 🙂
  • @Kusalananda olen ' mennyt eteenpäin ja muokannut kysymystä vastaamaan ongelmaa paremmin. Tämän pitäisi estää virheellisiä Google-hakuja osumasta sivulle. Kiitos tiedoista!

Vastaa

Voit tehdä kaikki yhdellä komennolla.

find /path/to -type f -execdir bash -c "printf "%s\n" "${@%.*}"" bash {} + 

Kommentit

  • Kiitos! Minun on todella luotava pari kopiota taulukosta, yksi valikosta, jonka tiedostonimi on muokattu, ja toinen, joka säilyttää alkuperäisen hakemiston arvon, jotta voin soittaa tiedostoon valikosta. On todella hämmästyttävää, kuinka paljon bash voi kuitenkin tehdä! Kyky upottaa kaikki yhteen komentoon räjäyttää minut edelleen! : D

Vastaa

Uskon, että haluat tehdä taulukon merkkijonon sijaan:

IFS=$"\n" # split on newline only set -o noglob # disable the glob part file_list=($(find . -name "*.*" -type f)) 

Tai bash 4.4+ -sovelluksella, ei rikkomatta tiedostopolkuja uudella rivillä:

readarray -td "" file_list < <(find . -name "*.*" -type f -print0) 

Sitten parametrilaajennuksen pitäisi toimia, vaikka tässä olisi järkevämpää käyttää uudelleen taulukon muuttujaa:

trimmed_file_list=("${file_list[@]%.*}") 

Koodinäytteessä olet tekemässä merkkijonoa Sitten pyydetään parametrilaajennusta poistamaan kaikki merkkijono viimeisen pistemerkin jälkeen.

Kommentit

  • Kiitos! Testaan sen heti, kun osun pöydälleni aamulla.
  • Tämä olettaa, että yksikään hakemiston tiedostonimi ei sisällä välilyöntejä tai huojuvia merkkejä.
  • @Wildcard, pitäisi olla viimeisin muokkaus.
  • @Wildcard Kiitos osoittimesta! ' m Luon tiedostot, jotka pudotetaan tähän hakemistoon ohjelmallisesti, joten sen ei pitäisi olla '.

Vastaus

Koodisi ei sisällä taulukoita. Lisäksi se lisää luettelon tiedostonimistä merkkijonoon, $file_list. Merkkijonon loppuosa on file3.png ja parametrisi korvaaminen poistaa merkkijonosta .png, jolloin sinulle jää yksi merkkijono tiedostonimiä viimeisellä tiedostonimellä ei ole tiedostonimen loppuliitettä.

Usean erillisen objektin (polunimen) lisääminen yhteen merkkijonoon hylkää komentosarjan toimimasta automaattisesti tiedostoissa, joiden nimet sisältävät välilyöntejä (tai mitä merkkijonoa käytetään) Taulukon käyttäminen ei auta, koska jaat silti find -alueen tyhjät alueet.


Leikkaa laajennus pois kaikista tavallisten tiedostojen tiedostonimistä nykyisessä hakemistossa tai sen alapuolella:

find . -type f -name "*.*" -exec sh -c " for pathname do printf "Would move %s to %s...\n" "$pathname" "${pathname%.*}" # mv -i "$pathname" "${pathname%.*}" done" sh {} + 

Tämä etsii tavallisia tiedostoja, joiden nimissä on vähintään yksi piste. Näiden tiedostojen polunimet syötetään erissä pieneen komentojonoon, joka silmukkaa niiden yli. Shell-komentosarja nimeää tiedostot uudelleen poistamalla tiedostonimen viimeisen pisteen ja kaiken sen jälkeen. Varsinainen mv -komento kommentoidaan turvallisuuden vuoksi.

find -komento toimii polunimien generaattorina sisäisen komentosarjan komentosarjan, ja voimme taata, että prosessoimme oikein välilyöntejä, uusia viivoja ja välilehtiä sisältävät polkunimet. Komentojen lähtöä ei tarvitse tallentaa muuttujiin.

Jos sinulla on joukko polkuja, jotka on mahdollisesti luotu käyttämällä

shopt -s globstar nullglob file_list=( **/*.* ) # get pathnames of files with dots in their names 

Sitten pystyt tuottamaan polunimet ilman loppuliitteitä

printf "%s\n" "${file_list[@]%.*}" 

Eikö tämä auttaisi sinua, en tiedä. Jos haluat käyttää niiden polkujen nimiä, joissa ei ole loppuliitteitä , sitten yllä olevan printf -komennon ulostulon käyttäminen olisi väärä asia (sinun ei tarvitse enää käsitellä outoa polunimeä). Joten kun ja kuinka poistat tiedostonimen jälkiliitteet riippuu siitä, mitä haluat tehdä tulokseen.

Liittyvät:

Kommentit

  • Kiitos! Taitosi bashille on hyvin ilmeistä! Kaapin vielä pintaa ' … Kiitos, että käytit aikaa auttaaksesi 🙂

Vastaa

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