ls -1 így sorolja fel az elemeimet:
foo.png bar.png foobar.png ...
A így:
foo bar foobar ...
(a dir csak .png fájlokat tartalmaz)
Valaki meg tudja mondani, hogyan kell használni az grep -t ebben az esetben?
Cél: Van egy szöveges fájlom, ahol az összes név fel van tüntetve a kiterjesztés. Olyan szkriptet szeretnék készíteni, amely összehasonlítja a szöveges fájlt a mappával, hogy megnézze, melyik fájl hiányzik.
Megjegyzések
Válasz
Ehhez a munkához csak a héjra van szükség.
POSIXly:
for f in *.png; do printf "%s\n" "${f%.png}" done
A következővel: zsh:
print -rl -- *.png(:r)
Megjegyzések
- Ott ‘ nincs szükség
printf-re; Aecho ${f%.png}elegendő lesz. - @Conrad: az echo használata bizonyos esetekben ‘ nem működik megfelelően, ha a fájlnév kötőjellel kezdje, vagy tartalmazzon elhagyott szekvenciákat.
- @DavidConrad: Lásd még: unix.stackexchange.com/a/65819/38906
- @DavidConrad Ezenkívül úgy gondolom, hogy a printf be van építve, csakúgy, mint az echo, valaki javítson ki, ha ‘ rossz vagyok
Válasz
ls -1 | sed -e "s/\.png$//"
A sed parancs eltávolítja (vagyis az üres karakterlánccal helyettesít) minden olyan sztringet .png, amely a végén található egy fájlnév.
A . \. néven kerül megkerülésre, így a sed mint szó szerinti . karakter, nem pedig a regexp . (ami azt jelenti, hogy illeszkedjen bármelyik ch-hez jelleg). A $ a sor végének horgonya, ezért nem egyezik a .png fájlnév közepén.
Hozzászólások
- Azt hiszem, hogy az OP bármilyen kiterjesztést meg akar törölni, de valószínűleg csak a ” utolsó “. Tehát módosítsa az egyébként jó válaszát a következővel:
sed 's/\.[^.]*$//' - igen, ez a regexp működik ebben az esetben … de ha az OP ezt akarja, akkor azt kell mondaniuk, ahelyett, hogy kifejezetten azt mondanák, hogy ” azt akarják, hogy a .png ”
- A
-1nem szükséges, mivel itt az alapértelmezett. - @jlliagre Egyetértek a cas véleményével, hogy a
-1meg kell adni. ‘ csak akkor van alapértelmezés, amikor a cső be van kapcsolva, ami némelyek számára rejtett meglepetés. Tehát annak egyértelművé tétele segít Ezt a forgatókönyveimben is megteszem, így tudom, hogy milyen o utput I ‘ m várok. - Figyelmeztetés A (
.png) egy újsoros karakter előtt még azt az.png-t is törli, és nem csak az utolsót. Jobb elkerülni az ls kimenetének csempézését és elemzését, gyakran jól rejtett meglepetéseket tartogat … (néhány szó és hivatkozás bővebben a válaszban).
Válasz
Ha csak a bash-t szeretné használni:
for i in *; do echo "${i%.png}"; done
Az grep címre kell törekednie, amikor megpróbál találni egyezéseket, nem pedig a sed megfelelőbb:
find . -maxdepth 1 -name "*.png" | sed "s/\.png$//"
Ha úgy dönt, hogy létre kell hoznia néhány alkönyvtárat, hogy rendet lehessen hozni a PNG-fájlokban, akkor könnyen módosíthatja:
find . -name "*.png" | sed "s/\.png$//"
Megjegyzések
- ls -1 | A sed ‘ s / .png // ‘ remekül működik. Köszönjük!
- A
findasedmegoldás asedmegoldással problémákat okozhat, ha talál egy fájlt, amelynek kulcsa (.png) szerepel a név részeként és közvetlenül egy újsoros karakter előtt. Jobb elkerülni afindvagy alskimenetének csövezését és elemzését, gyakran jól rejtett meglepetéseket tartogat … (néhány szó és a válaszban többet utal). - Valószínűleg az
find-t cserélje le valamire, például azechokifejezésre az utolsó példában. Nem világos, hogy afindmilyen célt szolgál ott, és az eredmények a könyvtárstruktúrától függenek (azaz van-e könyvtáradfiles.png) - @BroSlow Frissítve valami értelmesebbre.
Válasz
Egy másik nagyon hasonló válasz (ezen meglepődtem egy adott változat még nem jelent meg):
ls | sed -n "s/\.png$//p"
- Nem kell a
-1opció alslehetőségre, mivel alsfeltételezi, hogy ha a standard kimenet nem “ta terminál (ebben az esetben ez a cső). - a
-nopció asedopcióra azt jelenti, hogy “ne nyomtassa ki a sort alapértelmezés szerint” - a
/popció a helyettesítés végén azt jelenti: “… és nyomtassa ki ezt a sort, ha helyettesítés történt”.
A net ennek az a következménye, hogy csak azokat a sorokat nyomtatja ki, amelyek .png végződésűek, eltávolítva. Vagyis ez kielégíti az OP kérdésének enyhe általánosítását is, ahol a könyvtár nem “csak .png fájlokat tartalmaz.
A technika gyakran hasznos azokban az esetekben, amikor egyébként használhatja a grep + sed programot.
Megjegyzések
- Tetszik az ellátás módja régebben írtad a választ. Ez a megoldás problémákat fog okozni a fájlnevekben, beleértve az új sorokat , nem fogja kinyomtatni a név első részét. Még inkább, ha csúnyább a kulccsal (
.png) az újsoros char előtt: ebben az esetben az alkatrészt png nélkül nyomtatja ki, és nem csak az utolsó részt törli. Gyakran javasoljuk, hogy elkerülje als, mert a problémák éppen ott rejtőzhetnek, ahol nem gondolkodik … - @Hastur Ön ‘ helyes , elvileg, és a híres oldal erről: don ‘ t parse ls további problémákat (és megoldásokat) sorol fel a kóros fájlnevek átadásakor. De a kezelés legjobb módja az, ha elkerüljük a kóros fájlnevek t (doh!); és ha tud ‘ t, vagy ha kell robusztusnak lenni velük szemben, akkor vagy használjon
findvagy – esetleg jobb – használjon erősebb nyelvet, mint ash, mint azok kezelésére (az a tény, hogyshképes minden nem ‘ nem jelenti azt, hogy ‘ minden esetben a legjobb választás). A héjat először a használhatóságra tervezték. - Elvileg egyetértek a használhatósággal kapcsolatban, de ez a változat kudarcot vall, ha minden egyes új sorban fájlnév van. Ez könnyen észrevétlenül történhet, például amikor egy sort egy pdf-ből másol és beilleszt egy GUI-ba, így csak azt gondolja, hogy kerülje a kóros fájlneveket .
- Ezenkívül az IMHO ‘ könnyű elkezdeni értelmezni a
lselemzést, de a jövőbeni problémákkal küzd. Gyakran készítünk szkripteket amit később használunk, amikor már elfelejtjük a határértéküket … (ez ‘ s ember, ez általában ‘ s). javaslatot tettem egyfindpéldára (-execés cső nélkül) akkor is, ha jobbnak (mert a tiszta héjnak) tartom, válaszoljon a cuonglm ‘ s , szilárd és posix kompatibilisre. - Nagyjából ezt tenném ‘, ha valamilyen okból el akarnám távolítani a csíkot a
.pngutótag a fájlnevek listájából.Nem ‘ nem tenném szkriptbe; ehelyett ‘ d csak beírom a parancsot a shell parancssorba. Ezzel emlékeztetne arra, hogy ‘ m feltételezem ” ésszel ” fájlnevek. Rengeteg olyan dolog van, amit ‘ egyszeri kézi parancsban teszek meg, amikor nyugodtan tehetek feltételezéseket arról, hogy mi ‘ az aktuális könyvtárban valószínűleg nem ‘ tennék egy olyan szkriptben, amelyet esetleg más kontextusban is újra felhasználhatnának.
Válasz
A következőre megyek: basename (feltételezve a GNU megvalósítását):
basename --suffix=.png -- *.png
megjegyzések
- Ne feledje, hogy ha csőben akarja használni, akkor hasznos lehet a GNU basename ‘ s
-z(vagy--zero) opció NUL-elválasztással (új sorral elválasztva) ) kimenet.
Válasz
Erre csak BASH parancsokat használhat (külső eszközök nélkül).
for file in *; do echo "${file%.*}"; done
Ez akkor hasznos, ha a / usr / bin nélkül van, és szépen működik a l Ilyen az is.
Válasz
nem volt elég?
ls -1 | sed "s/\.png//g"
vagy általában, ez
ls -1 | sed "s/\.[a-z]*//g"
eltávolítja az összes kiterjesztést
Megjegyzések
- Ez volt, de a többi megoldás is működik.
- Minden Unix / Unix Like rendszer telepítve van (vagy kellett volna)
sed, mivel ez egy kötelező segédprogram a szabvány szerint. - Valóban, de a
lsegyébként is megteszi ezt az opciót, ha a kimenete nem terminál, amire ez a helyzet. - Figyelmeztetés
ls -1 | sed 's/\.[a-z]*//g'nem fog sikerülni, ha van egy fájlnévImage.png.jpg.pngnéven, amikor a kulcs folyamatosan vágódik (.png). A Unix alatt furcsa fájlnevekThe new art of working on .png?files and other formats.pngnéven engedélyezettek, ahol a?egy új vonalas karakter. Sajnos minden olyan probléma felmerül, amely alskimenetet egyszerűen csövezi / elemzi. ms ilyen esetek kezelése … - Miért a
gminősítő? A\.pngüzenetet csak a sor végén szeretné eltávolítani, nem minden alkalommal, amikor megjelenik.
Válasz
Nem biztonságos a ls elemzése vagy a find [ 1 , 2 ]
Nem biztonságos a ls vagy a find kimenetét elemzi (és átadja), főleg azért, mert a fájlnevekben nem szokásos karakterek, mint az új sor , a fül … Itt egy tiszta shell ciklus fog működni [ cuonglm ] .
Még a find parancs is not piped a -exec működni fog:
find ./*.png -exec basename {} .png \;
Frissítések / megjegyzések : A find . segítségével akár a rejtett fájlokat is megkeresheti, vagy find ./*.png hogy csak a nem rejtetteket kapja meg. A find *.png -exec ... használatával problémát okozhat, ha egy .png nevű fájl volt jelen, mert a find opcióként kapja meg. Hozzáadhat -maxdepth 0, hogy elkerülje a Dir_01.png vagy find ./*.png -prune -exec ... nevű könyvtárakban való leereszkedést. maxdepth nem megengedett (köszönöm Stéphane). Ha el akarja kerülni a könyvtárak felsorolását, adja hozzá a -type f opciót (amely kizárna más, nem szabályos fájlokat is). Nézze meg a man t, hogy teljesebb körképet nyújtson az összes rendelkezésre álló lehetőségről, és ne felejtse el ellenőrizni, hogy a POSIX-kompatibilisek-e a jobb hordozhatóság érdekében.
Néhány szó tovább
Előfordulhat például, hogy ha a dokumentumról lemásolja a címet és beilleszti a fájlnévbe, egy vagy több új sor a fájlnévben is befejeződik.Még olyan szerencsétlenek is lehetünk, hogy egy cím tartalmazhatja azt a kulcsot is, amelyet közvetlenül az új sor előtt kell használnunk:
The new art of working on .png files and other formats.
Ha tesztelni szeretne, akkor hozzon létre ilyen fájlneveket a parancsokkal
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"
Az egyszerű /bin/ls *png ? a nem nyomtatható karakterek helyett
A file with two lines?and This is the second.png The new art of working on .png?files and other formats.png
Minden esetben, amikor a ls vagy find kimenetet csatolja, a következő parancsnak nem lesz megértése ha a jelenlegi sor új fájlnévből származik, vagy ha egy újsor karaktert követ a precedens fájlnév ben. Valóban csúnya név, de még mindig törvényes.
Egy shell-ciklus egy Parameter-Expansion héjjal, ${parameter%word}, mindkettőben a (z) printf vagy echo változata [ cuonglm ], [ Anthon1 ] .
for f in *.png; do printf "%s\n" "${f%.png}" ; done
A man oldalról a Shell paraméter kibővítésének [ 3 ]
$ {parameter% word}
$ {parameter %% word}… a kiterjesztés eredménye a legrövidebb egyezési mintájú (% eset) vagy a a leghosszabb egyező minta (a %% eset) törölve.
Megjegyzések
- Szintén a
findparancs egy kicsit változó (például ha létezik egyfiles.pngnevű könyvtár) - Kedves @BroSlow, amikor a választ fentebb írtam I 13 (az összes) abban a pillanatban jelen lévő változat ból próbálkozott, parancssoronként, egy parancsfájlban, amelyet egy shell meghívás argumentumaként indítottak el. Kérem, tegye ugyanezt, és mondja el, ha a várt módon viselkednek. Tesztjeimet a következővel végeztem:
bash 4.3.11, dash 0.5.7-4, zsh (ha szükséges) 5.0.2. Nyugodtan olvassa el ezt a bejegyzést , amely még valamit hozzáad. Egyetértek a piping megjegyzésével afindkimeneténél, ehhez kifejezetten javasoltam-execés a címbe írtam.:-). - Olvassa el újra a wikit. Még mindig úgy gondolom, hogy meg kell adnia a példáját, mivel ‘ ez az, amit ‘ tárgyalunk itt. A
lsmodern verzióinak többségéhez nincs semmi probléma, amikor a kimenetet átirányítják vagy átirányítják, de amint a wiki említi, nem biztos, hogy mindenki számára használható. A legtöbb csak akkor fogja beilleszteni a?-t a speciális karakterek helyébe, ha a kimenetet a terminálra küldi. azaz tegye a következőt:echo *.png | od -césls *.png | od -c. Az újsoros probléma nem alsprobléma, hanem ‘ minden olyan parancs problémája, amely nem ‘ t null végződik a cső mindkét oldalán. -
printf "${f%.png}\n"téves. Az első argumentum a formátum, nem szabad ‘ használni a változó adatokat. Akár DoS-sebezhetőség is lehet (próbálkozzon például egy%1000000000s.pngfájllal). - Ön ‘ d
find ./*.png -prune -exec...szükséges, vagy ‘ d problémái vannak a-kezdetű fájlnevekkel írja be a könyvtárat, vegye figyelembe, hogy az-maxdepthnem hordozható)
Válasz
A rev használata:
ls -1 | rev | cut -f 2- -d "." | rev
rev megfordítja az összes húrok (vonalak); mindent levágsz az első “” után. és a rev újra megfordítja a maradékot.
Ha grep “alma” -t szeretne:
ls -1 | rev | cut -f 2- -d "." | rev | grep "alma"
Megjegyzések
- A
-1nem szükséges, itt ez az alapértelmezett. - Ez csúnyán meghiúsul a
My.2016.Summer.Vacation.png - @DavidConrad my bad: / javítottam a következőre:
cut -f 2- - Most azzal a fájllal működik, de még nem egy
.pngés egy új vonallal rendelkező fájllal … Javasoljuk, hogy ne elemezze alsmert nagyon szereti elrejteni a meglepetéseket … 🙂
Válasz
Ha tudnám, hogy a könyvtárban csak olyan fájlok vannak, amelyek kiterjesztése .png, akkor csak futtattam volna: ls | awk -F. "{print $1}"
Ez visszaadja az első “mezőt” a következőre: bármi, ahol van fájlnév.kiterjesztés.
Példa:
[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
Megjegyzések
- Sajnos ez nem fog sikerülni a fájlnevek egynél több
.névvel,Image.1.pngnéven, sőt a nem szépeknél is nevek , benne speciális karakterekkel. új vonallal vagy azzal, amelyet (beviteli) rekord elválasztóként fog használni aawk,RSmezőben. Javasoljuk, hogy kerülje alskimenet elemzését, mert imádja elrejteni azokat a problémákat, amelyek felmerülnek, amikor nem számíthat rá. További információt a 1 vagy a 2 hivatkozásban talál. A BTW jó ötlet az awk használatára … Néhány példát egy válaszba adtam. - Igaz, azonban a Colin által nyújtott minta alapján ez nagyon jól fog működni. Annak érdekében, hogy az Ön által javasolt esetnek megfelelően működjön, ‘ valószínűleg módosítom a következőre: [rsingh @ rule51 TESTDIR] $ ls | sed -e ‘ s / .png $ // ‘ 10 1 2 3 4 5 6 7 8 9 harry.the.bunny izé .a.png.filename Nem próbál nehéz lenni, de tekintettel a Colin ‘ szükségleteire, nem vagyok biztos abban, id = “cb80420c6c”>
ls elemzése.
. alól a \. belsejében a sed -e 's/\.png$//', de így az imént írt válasz lesz belőle. 🙁 note2] megpróbálhatja használni a awk -t valami hasonlóval, mint ls | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}' … de meglesz mindig az a probléma merül fel, hogy az awk nem tudja, hogy a sor érkezik-e, a fájlnév új sorát követi vagy sem. Próbáltam jobbat mondani a válaszomban. Válasz
az Ön szerint comment “Van egy szöveges fájlom, ahol az összes név kiterjesztés nélkül szerepel. Szeretnék egy PHP szkriptet készíteni, amely összehasonlítja a szöveges fájlt a mappával, hogy megnézze, melyik fájl hiányzik”:
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
és fordítva:
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)
Válasz
ls -l | sed "s/\.png$//"
A @roaima által kiemelt legpontosabb módszer. A megúszott \.png fájlok nélkül a a_png.png nevű fájlok a következők lehetnek: a_.
Megjegyzések
- A
ls -lhasználatával, ahogy te teszed, megadod a fájl adatait, az OP nem ezt kérte kb.
Válasz
Egyszerű shell sor (ksh, bash vagy zsh; nem kötőjel):
set -- *.png; printf "%s\n" "${@%.png}"
Egyszerű függvény (nem kiterjesztésből):
ne(){ set -- *.png; printf "%s\n" "${@%.png}"; }
Vagy egy olyan funkció, amely eltávolítja bármely megadott kiterjesztés (alapértelmezés szerint png):
ne(){ ext=${1:-png}; set -- *."$ext"; printf "%s\n" "${@%.${ext}}"; }
Használja:
ne jpg
Ha a kimenet csillag *, akkor nincs ilyen kiterjesztésű fájl.
Válasz
Kipróbálhatja a következő feed awk-t. A szuperátorod kimenete a “”. és mivel minden fájljának neve lesz.png, kinyomtatja az első oszlopot:
ls | awk -F"." "{print $1}"
Válasz
Ha van hozzáférése a sed-hez, akkor ez jobb, mivel az utolsó fájlkiterjesztést eltávolítja, függetlenül attól, hogy mi ez (png, jpg, tiff stb …)
ls | sed -e "s/\..*$//"
Megjegyzések
- Szünetek olyan fájlnevekhez, mint
this.is.a.dotty.txt. Próbáld meg inkább as/\.[^.]*$//-t.
.-et. Bár a konvenció azt mondja, hogy a fájlokat a végén nevezze el.png-nek, nincs oka annak, hogy ‘ nem lehet egyfoo.zipvagymy.picture.20160518vagy csakmypic.lsés alsésfindkimenetét csövezni, főleg azért, mert lehetőség nyílik anewline,` tab karakter a fájlnévben. Ha a fájlnévThe new art of working on .png\NEWLINE files and other formats, a javasolt megoldás nagy része problémákat okoz.