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
-1
nem szükséges, mivel itt az alapértelmezett. - @jlliagre Egyetértek a cas véleményével, hogy a
-1
meg 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
find
ased
megoldás ased
megoldá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 afind
vagy als
kimeneté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 azecho
kifejezésre az utolsó példában. Nem világos, hogy afind
milyen 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
-1
opció als
lehetőségre, mivel als
feltételezi, hogy ha a standard kimenet nem “ta terminál (ebben az esetben ez a cső). - a
-n
opció ased
opcióra azt jelenti, hogy “ne nyomtassa ki a sort alapértelmezés szerint” - a
/p
opció 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
find
vagy – esetleg jobb – használjon erősebb nyelvet, mint ash
, mint azok kezelésére (az a tény, hogysh
ké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
ls
elemzé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 egyfind
pé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
.png
utó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
ls
egyé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.png
né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.png
néven engedélyezettek, ahol a?
egy új vonalas karakter. Sajnos minden olyan probléma felmerül, amely als
kimenetet egyszerűen csövezi / elemzi. ms ilyen esetek kezelése … - Miért a
g
minő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
find
parancs egy kicsit változó (például ha létezik egyfiles.png
nevű 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 afind
kimeneté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
ls
modern 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 als
problé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.png
fá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-maxdepth
nem 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
-1
nem 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 als
mert 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.png
né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
,RS
mezőben. Javasoljuk, hogy kerülje als
kimenet 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 -l
haszná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.zip
vagymy.picture.20160518
vagy csakmypic
.ls
és als
ésfind
kimeneté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.