A fájlnévkiterjesztés eltávolítása a bash fájlnevek listájáról

Megpróbálom eltávolítani a fájlnévkiterjesztést az alábbiak által létrehozott fájlok listájáról bash szkript:

 #!/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[@]}" 

Ez a kiterjesztés levágja a kiterjesztést a lista utolsó bejegyzéséről, de a korábbiakat nem.

Például a következő listát szeretném:

 file1.pdf file2.pdf file3.png 

Legyen

 file1 file2 file3 

De ehelyett kapom:

 file1.pdf file2.pdf file3 

Ezt nem szeretném ciklusban csinálni, a paraméterek kibővítését szeretném használni. Kerülni akarom a vágást, mert csak a fájl utolsó kiterjesztését akarom eltávolítani.

A paraméterek kibővítésével kapcsolatban elég sok téma található, és úgy tűnik, hogy a bash fulladhat a find” új sorok használata … Nem igazán vagyok biztos benne. Ha egy másik, már létező téma megmagyarázza ezt a kérdést, akkor nem fogom fel teljesen, mi folyik itt.

Úgy tűnik témák kapcsolódó, de úgy tűnik, hogy nem oldja meg a problémámat:

Megjegyzések

  • A cím tömböket említ, de a kódban nincs tömb.
  • @Kusalananda Köszönöm! ' rájöttem, hogy mióta kérdeztem. Még mindig tanulok 🙂
  • @Kusalananda ' tovább mentem, és módosítottam a kérdést, hogy jobban illeszkedjen a problémához. Ez megakadályozhatja, hogy a hibás google keresések eljussanak az oldalra. Köszönjük az információkat!

Válasz

Mindent egy parancsban tehet meg.

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

Megjegyzések

  • Köszönöm! Valójában létre kell hoznom néhány tömböt a tömbből, egyet egy olyan menühez, amelynek módosított fájlneve van, és egyet, amely megtartja az eredeti index értékét, hogy a fájlt a menüből lehívhassam. Valóban elképesztő, hogy bash mennyit tud csinálni! Az a képesség, hogy mindent egy parancsba ágyazok, még mindig elrobbant! : D

Válasz

Úgy gondolom, hogy tömböt szeretne készíteni karakterlánc helyett:

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

Vagy a bash 4.4+ verzióval, nem feltörve az új sor karakterű fájlútvonalakat:

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

Ekkor a paraméterbővítésének működnie kell, bár itt érdemes lenne újra tömb változót használni:

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

A kódmintában egy karakterláncot készít majd megkérdezi a paraméterbővítést, hogy távolítson el mindent a teljes karakterlánc utolsó pontja után.

Megjegyzések

  • Köszönjük Amint reggel beütök az íróasztalomra, kipróbálom.
  • Ez azt feltételezi, hogy az adott könyvtár egyetlen fájlneve sem tartalmaz szóközt vagy tompító karaktert.
  • @Wildcard, a legutóbbi szerkesztés címezte.
  • @Wildcard Köszönjük a mutatót! ' m generálom az ebbe a könyvtárba ejtett fájlokat programozottan, így nem lehet ' probléma.

Válasz

A kód nem tartalmaz tömböket. Ezenkívül a fájlnevek listáját egy sztringbe helyezi, $file_list. A karakterlánc tartalma a következővel fog végződni: file3.png, és a paraméter-helyettesítésed eltávolítja a (z) .png elemet a karakterláncból, így egyetlen fájlnév-karakterlánc marad, ahol az utolsó fájlnév nem rendelkezik fájlnév utótaggal.

Több különálló objektum (útvonalnév) egyetlen karaktersorozatba helyezése automatikusan kizárja a parancsfájl megfelelő működését azokban a fájlokban, amelyek neve szóközt tartalmaz (vagy bármilyen karaktert használ a karakterlánc). A tömb használata nem segít, mivel továbbra is megosztaná a find kimenetét a szóközökön.


A kiterjesztés levágása a szokásos fájlok összes fájlnevéről az aktuális könyvtárban vagy alatt:

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

Ez olyan rendszeres fájlokat keres, amelyek neve legalább egy pontot tartalmaz. Ezeknek a fájloknak a elérési útjait kötegekben adják meg egy kis shell parancsfájlba, amely átfut. A shell szkript átnevezi a fájlokat azáltal, hogy eltávolítja a fájlnév utolsó pontját és minden utána következőt. A tényleges mv parancsot a biztonság kedvéért megjegyezzük.

A find parancs a belső shell parancsfájl, és garantáltan helyesen dolgozzuk fel a szóközöket, új sorokat és tabulátorokat tartalmazó útvonalneveket. Nem szükséges a parancsok kimenetét változókban tárolni.

Ha van egy tömb útvonalnév, amelyet esetleg a

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

használatával hoztak létre, akkor a utódok utótag nélkül is kiadhatók

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

Hogy ez segítene-e, nem tudom. Ha használni akarod valamihez utótag nélküli útvonalneveket valamihez , akkor a fenti printf parancs kimenetének használata a helytelen tennivaló lenne (visszatérne, ha nem kezelné újra a különös útvonalnevet). és a fájlnév utótagok törlésének módja attól függ, hogy mit szeretnél csinálni az eredménnyel.

Kapcsolódó:

Megjegyzések

  • Köszönöm! A bash elsajátítása nagyon nyilvánvaló! ' még mindig a felszínen kaparok … Köszönöm, hogy szánt időt a segítségére 🙂

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük