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:
- Hogyan távolíthatom el egy fájlnév kiterjesztését egy shell parancsfájlban?
- Shell paraméterek bővítése tömbökön
- Fájlnév eldobása kiterjesztések a -exec kereséssel
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 🙂