ls -1
listaa elementtini näin:
foo.png bar.png foobar.png ...
Haluan sen listattavan ilman .png
näin:
foo bar foobar ...
(dir sisältää vain .png
-tiedostoja)
Voiko joku kertoa minulle, miten grep
käytetään tässä tapauksessa?
Tarkoitus: Minulla on tekstitiedosto, jossa kaikki nimet on lueteltu ilman laajennus. Haluan tehdä komentosarjan, joka vertaa tekstitiedostoa kansioon nähdäksesi, mikä tiedosto puuttuu.
Kommentit
Vastaa
Tarvitset vain kuoren tähän työhön.
POSIXly:
for f in *.png; do printf "%s\n" "${f%.png}" done
Kanssa zsh
:
print -rl -- *.png(:r)
kommentit
- Siellä ’ ei tarvita
printf
;echo ${f%.png}
riittää. - @Conrad: kaiun käyttäminen ei toimi ’ ei toimi joissakin tapauksissa oikein, jos tiedoston nimi aloita viivalla tai sisältää pakotettuja sekvenssejä.
- @DavidConrad: Katso myös unix.stackexchange.com/a/65819/38906
- @DavidConrad Lisäksi uskon, että printf on sisäänrakennettu, aivan kuten kaiku, joku korjaa minut, jos olen ’ väärässä
Vastaus
ls -1 | sed -e "s/\.png$//"
sed
-komento poistaa (eli se korvaa tyhjän merkkijonon) mikä tahansa merkkijono .png
, joka löytyy kohteen lopusta tiedostonimi.
.
vältetään nimellä \.
, joten kirjaimellisena .
-merkkinä regexp .
-merkin sijaan (mikä tarkoittaa, että vastaa mitä tahansa ch: tä luonne). $
on rivin lopussa oleva ankkuri, joten se ei sovi .png
tiedostonimen keskelle.
Kommentit
- Luulen, että OP haluaa minkä tahansa laajennuksen poistamisen, mutta luultavasti vain ” viimeinen ”. Joten ehkä muokkaa muuten hyvää vastaustasi:
sed 's/\.[^.]*$//'
- kyllä, regexp olisi toimi siinä tapauksessa … mutta jos OP haluaa niin, heidän tulisi sanoa niin sen sijaan, että sanottaisiin nimenomaisesti, että he ” haluavat sen olevan luettelossa ilman .png ”
-
-1
ei ole välttämätön, koska se on tässä oletusarvo. - @jlliagre Olen samaa mieltä cas kanssa, että
-1
tulisi määritellä. Se ’ on vain oletusarvo, kun putki kytketään päälle, mikä on piilotettu yllätys joillekin. Joten sen selkeyttäminen auttaa Teen tämän myös käsikirjoituksissani, jotta tiedän millainen o utput I ’ odotan. - Varoitus Jos kyseessä on avaimen sisältävä tiedostonimi (
.png
) ennen uuden rivin merkkiä pyyhit jopa.png
eikä vain viimeisen. Parempi on välttää ls: n tuotoksen putkiminen ja jäsentäminen, se varaa usein hyvin piilotettuja yllätyksiä … (vastauksessa on joitain sanoja ja viitteitä).
Vastaa
Jos haluat käyttää vain bash-tiedostoa:
for i in *; do echo "${i%.png}"; done
Sinun tulisi tavoittaa grep
, kun yrität löytää osumia, et poista / korvaa sitä, että sed
sopivampi:
find . -maxdepth 1 -name "*.png" | sed "s/\.png$//"
Kun olet päättänyt, että sinun on luotava joitain alihakemistoja järjestyksen luomiseksi PNG-tiedostoihisi, voit vaihtaa sen helposti muotoon:
find . -name "*.png" | sed "s/\.png$//"
Kommentit
- ls -1 | sed ’ s / .png // ’ toimii hyvin. Kiitos!
-
find
johdettu –sed
-ratkaisu voi aiheuttaa joitain ongelmia, jos löydät tiedoston, jonka avain (.png
) on osa nimeä ja juuri ennen uuden rivin merkkiä.find
– tails
-lähtöä on parempi välttää piilottaa ja jäsentää, se varaa usein hyvin piilotettuja yllätyksiä … (joitain sanoja ja viittauksia lisää vastaukseen). - Korvaa todennäköisesti
find
viimeisellä esimerkillä jotainecho
. Ei ole selvää, mikä tarkoitusfind
palvelee siellä ja tulokset riippuvat hakemistorakenteesta (ts. Jos sinulla on hakemistofiles.png
) - @BroSlow Päivitetty järkevämmäksi.
Vastaa
Toinen hyvin samanlainen vastaus (olen yllättänyt tämän tietty variantti ei ole vielä ilmestynyt) on:
ls | sed -n "s/\.png$//p"
- Et tarvitse
-1
vaihtoehtols
, koskals
olettaa, että jos vakiolähtö ei ole ”ta” -liitin (tässä tapauksessa se on putki). -
-n
-vaihtoehtosed
tarkoittaa ”älä tulosta viivaa oletuksena” - Korvauksen lopussa oleva vaihtoehto
/p
tarkoittaa … ja tulosta tämä rivi, jos korvaus tehtiin.
Verkko seurauksena on tulostaa vain ne rivit, jotka päättyvät .png
-merkkiin poistettu. Toisin sanoen tämä palvelee myös OP: n kysymyksen hieman yleistämistä, jossa hakemisto ”ei sisällä vain .png
-tiedostoja.
sed -n
-tekniikka on usein hyödyllinen tapauksissa, joissa muuten saatat käyttää grep + sed-toimintoa.
Kommentit
- Pidän hoidon tavasta kirjoitit vastauksesi. Tämä ratkaisu aiheuttaa ongelmia tiedostonimissä, mukaan lukien uudet rivit , se ei tulosta nimen ensimmäistä osaa. Vielä enemmän, jos se on ikävämpi avaimella (
.png
) ennen uuden rivin merkkiä: tällöin osa tulostetaan ilman png-tiedostoa eikä tyhjennetä vain viimeistä osaa. Usein ehdotetaan, ettäls
koska ongelmat voidaan piilottaa juuri sinne, mistä et ajattele … - @Hastur Sinä ’ korjata , periaatteessa, ja kuuluisa sivu aiheesta don ’ t parse ls listaa muita ongelmia (ja ratkaisuja) patologisten tiedostonimien luovutuksessa. Mutta paras tapa käsitellä sitä on välttää patologisten tiedostonimien käyttöä (doh!); ja jos pystyt ’ t tai jos täytyy olla vankka heitä vastaan, käytä joko
find
tai – mahdollisesti parempi – käytä tehokkaampaa kieltä kuinsh
niiden hallitsemiseksi (se, ettäsh
voi tehdä kaikki ei tarkoita ’ t, että se ’ on kussakin tapauksessa paras valinta). Kuori on suunniteltu ensin käytettäväksi. - Olen periaatteessa samaa mieltä käytettävyydestä, mutta tämä muunnelma epäonnistuu, kun jokaisella uudella rivillä on tiedostonimi . Tämä voi tapahtua helposti huomaamatta, esimerkiksi kun kopioit ja liität rivin pdf: stä graafiseen käyttöliittymään, joten luulet vain välttävän patologisia tiedostonimiä .
- Lisäksi IMHO ’ on helppo aloittaa jäsentely
ls
, mutta se on tulevien ongelmien edessä. Teemme usein komentosarjoja jota käytämme myöhemmin, kun unohdamme jo niiden rajan … (se ’ on ihminen, se ’ on tavallista). I ehdotin esimerkkiäfind
(-exec
ja ilman putkea) vaikka katson paremman (koska puhdas kuori), vastaa cuonglm ’ yhteen , kiinteään ja posix-yhteensopivaan. - Tämä on melkein mitä minä ’ tekisin, jos jostain syystä halusin poistaa nauhan
.png
pääte tiedostojen nimiluettelosta.En halua ’ laittaa sitä komentosarjaan; sen sijaan ’ d vain kirjoitan komennon komentokehotteeseen. Näin tekeminen olisi muistutus siitä, että olen ’ m olettaen ” järkevän ” tiedostonimet. On paljon asioita, joita ’ teen kertakäyttöisessä manuaalisessa komennossa, kun voin tehdä vapaita oletuksia siitä, mitä ’ nykyisessä hakemistossa, en todennäköisesti ’ tekisi komentosarjassa, jota saatetaan käyttää uudelleen jossakin muussa yhteydessä.
Vastaa
Menen hakemaan basename
(olettaen, että GNU on toteutettu):
basename --suffix=.png -- *.png
Kommentit
- Huomaa, että jos haluat käyttää sitä putkessa, voi olla hyödyllistä käyttää GNU-basenimeä ’ s
-z
(tai--zero
) vaihtoehto tuottaa NUL-erotettu (uuden rivillä erotetun sijasta) ) output.
Vastaa
Voit käyttää siihen vain BASH-komentoja (ilman ulkoisia työkaluja).
for file in *; do echo "${file%.*}"; done
Tämä on hyödyllistä, kun olet ilman / usr / bin -ohjelmaa ja toimii mukavasti tiedostonimillä l kuten tämä.is.image.png ja kaikille laajennuksille.
vastaus
ei ollut tarpeeksi?
ls -1 | sed "s/\.png//g"
tai yleensä tämä
ls -1 | sed "s/\.[a-z]*//g"
poistaa kaikki laajennukset
kommentit
- Se oli, mutta muutkin ratkaisut toimivat.
- Kaikissa Unix / Unix Like -järjestelmissä on (tai pitäisi olla)
sed
asennettu, koska se on pakollinen apuohjelma standardin mukaan. - Tosiaankin, mutta
ls
tekee sen joka tapauksessa ilman tätä vaihtoehtoa, kun sen lähtö ei ole päätelaite, kuten tässä tapauksessa on. - Varoitus
ls -1 | sed 's/\.[a-z]*//g'
epäonnistuu, jos tiedostonimiImage.png.jpg.png
leikkaa koko avaimen (.png
). Unix-kohdassa sallitaan outoja tiedostonimiä nimelläThe new art of working on .png?files and other formats.png
, jossa?
on uuden rivin merkki. Valitettavasti kaikki ongelmat, jotka yksinkertaisesti liittävät / jäsentävätls
-lähdön, aiheutuvat ongelmasta MS hallitsee tällaisia tapauksia … - Miksi
g
-merkintä? Haluat poistaa\.png
vain rivin lopussa, ei aina, kun se ilmestyy.
Vastaa
Ei ole turvallista jäsentää ls
tai liittää find
[ 1 , 2 ]
Ei ole turvallista jäsentää (ja toipua) ls
– tai find
-lähtö lähinnä siksi, että se löytyy tiedostojen nimistä muut kuin tavalliset merkit uusi rivi , välilehti … Tässä puhdas kuorisykli toimii [ cuonglm ] .
Jopa find
-komento ei lähetetty -vaihtoehdolla -exec
toimii:
find ./*.png -exec basename {} .png \;
Päivitykset / Muistiinpanot : Voit käyttää find .
-ohjelmaa jopa piilotettujen tiedostojen etsimiseen tai find ./*.png
saada vain piilotetut. Kohdassa find *.png -exec ...
sinulla voi olla ongelmia siinä tapauksessa, että siinä oli tiedosto nimeltä .png
, koska haku saa sen vaihtoehtona. Voit lisätä -maxdepth 0
välttääksesi laskeutumista hakemistoihin nimeltään Dir_01.png
tai find ./*.png -prune -exec ...
kun maxdepth ei ole sallittu (kiitos Stéphane). Jos haluat välttää näiden hakemistojen luetteloimista, sinun on lisättävä vaihtoehto -type f
(joka sulkisi pois myös muita epätyypillisiä tiedostoja). Tarkastele man
-sivustoa saadaksesi täydellisemmän panoraaman kaikista käytettävissä olevista vaihtoehdoista. Muista tarkistaa, että ne ovat POSIX-yhteensopivia, jotta siirrettävyys paranee.
Joitakin sanoja enemmän
Voi esimerkiksi tapahtua, että kopioimalla otsikko dokumentista ja liittämällä se tiedostonimeen, yksi tai useampi uusi rivi päättyy itse tiedostonimeen.Voimme olla jopa niin onnekkaita, että otsikko voi sisältää jopa avaimen, jota meidän on käytettävä juuri ennen uutta riviä:
The new art of working on .png files and other formats.
Jos haluat testata, voit luo tällaisia tiedostojen nimiä komennoilla
touch "A file with two lines"$"\n""and This is the second.png" touch "The new art of working on .png"$"\n""files and other formats.png"
Yksinkertainen /bin/ls *png
tuottaa ?
tulostamattomien merkkien sijaan
A file with two lines?and This is the second.png The new art of working on .png?files and other formats.png
Kaikissa tapauksissa, joissa putki -viestin ls
tai find
lähtöä seuraavalla komennolla ei ole vihjeitä ymmärtää jos nykyinen rivi tulee uudesta tiedoston nimestä tai jos se seuraa newline -merkkiä ennakkotapauksessa tiedoston nimi . ikävä nimi todellakin, mutta silti laillinen.
Kuorisykli, jossa on komentotulkki Parameter-Expansion, ${parameter%word}
, molemmissa variantti, jossa on printf
tai echo
, toimii [ cuonglm ], [ Anthon1 ] .
for f in *.png; do printf "%s\n" "${f%.png}" ; done
Man-sivulta Shell-parametrilaajennuksen [ 3 ]
$ {parametri% word}
$ {parametri %% word}… laajennuksen tulos on parametrin arvo, jolla on lyhyin vastaava kuvio (%-tapaus) tai pisin vastaava kuvio (tapaus %%) poistettu.
Kommentit
- Myös
find
-komento on bittimuuttuja (esimerkiksi jos on hakemisto nimeltäfiles.png
) - Hyvä @BroSlow, kun kirjoitin vastauksen yllä I kokeillut 13 (kaikkia) muita läsnäolevia muunnelmia sillä hetkellä komentorivillä komentosarjassa, joka käynnistettiin kuoren kutsun argumenttina. Ole hyvä ja tee sama ja kerro minulle, jos he käyttäytyvät odotetulla tavalla. Tein testini
bash 4.3.11
-viivalla, viiva 0,5,7-4, zsh (tarvittaessa) 5.0.2. Voit vapaasti lukea tämän viestin , joka lisää jotain enemmän. Olen samaa mieltä siitä, että pipingfind
-lähtö on tuotu, tähän ehdotin nimenomaisesti-exec
ja kirjoitin otsikkoon.:-)
. - Lue wiki uudelleen. Mielestäni sinun on edelleen esitettävä esimerkkisi, koska ’ s mitä ’ käsitellään täällä. Ja suurimmalle osalle
ls
-sovelluksen moderneista versioista ei ole mitään ongelmaa, kun lähtö lähetetään tai ohjataan uudelleen, mutta kuten wikissä mainitaan, se ei välttämättä toimi kaikille. Suurin osa lisää?
-merkin erikoismerkkien tilalle vain, kun lähtö lähetetään päätelaitteelle. so. teeecho *.png | od -c
jals *.png | od -c
. Uuden rivin kysymys ei ole ongelmals
, se ’ on ongelma mille tahansa komennolle, joka ei ’ t null päättyy putken molemmin puolin. -
printf "${f%.png}\n"
on väärä. Ensimmäinen argumentti on muoto, sinun ei pitäisi ’ käyttää muuttujan tietoja siellä. Voidaan jopa nähdä DoS-haavoittuvuutena (kokeile esimerkiksi%1000000000s.png
-tiedostoa). - Sinä ’ d tarvitset
find ./*.png -prune -exec...
tai sinulla ’ d on ongelmia tiedostonimien kanssa, jotka alkavat-
(ja kirjoita hakemisto, huomaa, että-maxdepth
ei ole kannettava)
Vastaa
Käytä rev
:
ls -1 | rev | cut -f 2- -d "." | rev
rev
kääntää kaikki kielet (viivat); leikkaat kaiken ensimmäisen ”” jälkeen. ja rev palauttaa jäännöksen.
Jos haluat grep
”alma”:
ls -1 | rev | cut -f 2- -d "." | rev | grep "alma"
Kommentit
-
-1
ei ole tarpeen, koska se on tässä oletusarvo. - Tämä epäonnistuu huonosti tiedostossa nimeltä
My.2016.Summer.Vacation.png
- @DavidConrad my bad: / Olen korjannut tiedostoon
cut -f 2-
- Nyt se toimii kyseisen tiedoston kanssa, mutta ei vielä sellaisen tiedoston kanssa, jossa on
.png
ja uusi rivi heti sen jälkeen … On suositeltavaa välttää jäsentääls
koska se rakastaa piilottaa yllätykset … 🙂
Vastaa
Jos tiesin, että hakemistossa on vain tiedostoja, joiden laajennuksena on .png, olisin juuri suorittanut: ls | awk -F. "{print $1}"
Tämä palauttaa ensimmäisen ”kentän” kohteelle mitä tahansa, missä on tiedostonimi. laajennus.
Esimerkki:
[rsingh@rule51 TESTDIR]$ ls 10.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png [rsingh@rule51 TESTDIR]$ ls | awk -F. "{print $1}" 10 1 2 3 4 5 6 7 8 9
kommentit
- Valitettavasti se epäonnistuu kaikissa tiedostonimet , joissa on enemmän kuin yksi
.
, kutenImage.1.png
ja jopa niissä, joissa ei ole kiva nimet , erikoismerkit sisällä. uutena rivinä tai sellaisena, jota käytät (syöttö) tietueiden erottimena kohdassaawk
,RS
.ls
-lähdön jäsentämistä on suositeltavaa välttää, koska se rakastaa piilottaa ongelman, joka syntyy, kun et odota. Voit lukea lisää viitteestä 1 tai 2 . BTW on kiva ajatus käyttää awk: tä. Lisääin joitain esimerkkejä yhteen vastaukseen. - Totta, kuitenkin, Colinin toimittaman näytteen perusteella se toimisi hienosti. Jotta se toimisi ehdottamassasi tapauksessa, ’ vaihdan sen todennäköisesti muotoon: [rsingh @ rule51 TESTDIR] $ ls | sed -e ’ s / .png $ // ’ 10 1 2 3 4 5 6 7 8 9 harry.pupu .a.png.filename Ei yritä olla vaikeaa, mutta kun otetaan huomioon Colinin ’ tarve, en ’ ole varma, mitä asia aiheuttaisi jäsennä ls.
- anteeksi … tajusin juuri, etten ’ näyttänyt hakemistoa tiedostoilla ennen kuin muokkaan ’ ls ’ [rsingh @ rule51 TESTDIR] $ ls 10.png 2.png 4.png 6.png 8.png harry.pupu. png 1.png 3.png 5.png 7.png 9.png whats.a.png.filename.png [rsingh @ rule51 TESTDIR] $ ls | sed -e ’ s / .png $ // ’ 10 1 2 3 4 5 6 7 8 9 harry.pupu .a.png.tiedostonimi
- Huomautus1 sinun on vältettävä
.
-kenttää kohdassa\.
sisälläsed -e 's/\.png$//'
, mutta niin siitä tulee vasta kirjoitettu vastaus. 🙁 huomautus2 , voit yrittää käyttääawk
jotain esimerkiksils | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'
… mutta sinulla on aina ongelma, jota awk ei tiedä, saapuuko viiva, seuraa vai ei uutta riviä tiedostonimen sisällä. Yritin sanoa vastauksessani paremmin. - Kiitos Hastur, unohdin sen :). Lisäksi ojensin awk: n käytön sedin hyväksi tässä tapauksessa.
Vastaa
omasi mukaan kommentti ”Minulla on tekstitiedosto, jossa kaikki nimet on lueteltu ilman laajennusta. Haluan tehdä PHP-komentosarjan, joka vertaa tekstitiedostoa kansioon nähdäksesi mikä tiedosto puuttuu”:
for file in $(cat yourlist) ; do [ -f "${file}.png" ] || { echo "$file : listed in yourlist, but missing in the directory" } done #assumes that filenames have no space... # otherwise use instead: # while IFS= read file ; do ...(same inner loop as above)... ; done < yourlist
ja päinvastoin:
for file in *.png ; do grep "^${file%.png}$" yourlist >/dev/null || { echo "$file: present in the directory but not listed in yourlist" } done #I assume there are no spaces/tabs/? before/after names in "yourlist". Change the script accordingly if there are some (or sanitize the list)
vastaus
ls -l | sed "s/\.png$//"
On tarkin menetelmä, jonka @roaima korosti. Ilman pakenemia \.png
-tiedostoja, joiden nimi on a_png.png
, luetellaan seuraavasti: a_
.
Kommentit
-
ls -l
, kuten teetkin, antaa tiedoston tiedot, joita OP ei pyytänyt noin.
Vastaus
Yksinkertainen kuoririvi (ksh, bash tai zsh; ei viivaa):
set -- *.png; printf "%s\n" "${@%.png}"
Yksinkertainen toiminto (Ei laajennusta):
ne(){ set -- *.png; printf "%s\n" "${@%.png}"; }
Tai toiminto, joka poistaa mikä tahansa annettu laajennus (png oletuksena):
ne(){ ext=${1:-png}; set -- *."$ext"; printf "%s\n" "${@%.${ext}}"; }
Käytä nimellä:
ne jpg
Jos lähtö on tähti *
, tällä laajennuksella ei ole tiedostoa.
Vastaa
Voit kokeilla seuraavaa syötteen awk: ta, jonka superatorisi tulos on ””. ja koska kaikilla tiedostoillasi on nimi.png, tulostat ensimmäisen sarakkeen:
ls | awk -F"." "{print $1}"
Vastaa
Jos sinulla on pääsy sediin, tämä on parempi, koska se poistaa viimeisen tiedostotunnisteen riippumatta siitä, mikä se on (png, jpg, tiff jne …)
ls | sed -e "s/\..*$//"
Kommentit
- Katkokset tiedostonimille kuten
this.is.a.dotty.txt
. Kokeile sen sijaans/\.[^.]*$//
.
.
. Vaikka yleissopimus kehottaa nimeämään tiedostosi.png
lopussa, en ole mitään syytä, miksi ’ ei voi olla png-tiedostoa nimeltäfoo.zip
taimy.picture.20160518
tai vainmypic
.ls
ja liittääls
– jafind
-lähtö lähinnä siksi, että mahdollisuus esiintyänewline
,` sarkainmerkki tiedostonimessä. Jos tiedostonimi onThe new art of working on .png\NEWLINE files and other formats
, monet ehdotetuista ratkaisuista aiheuttavat ongelmia.