Chci přejmenovat více souborů ve stejném adresáři pomocí skriptu Bash. Názvy souborů jsou následující:
file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p
Chci přejmenovat na následující formát:
file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p
Četl jsem o příkazu rename a zkusil jsem to udělat tímto způsobem, ale nic to nedělá, myslím, že mám otázky ohledně syntaxe. Pak jsem četl, že smyčku můžete vytvořit pomocí příkazu mv takto:
for file in cmpsms*2014*.p; do mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}" done
Ale nemohu přejmenovat soubory. Co dělám špatně?
Komentáře
Odpověď
Měli jste pravdu, když jste nejprve zvážili přejmenování. Syntaxe je trochu podivná, pokud nejste zvyklí na regulární výrazy, ale je to zdaleka nejrychlejší / nejkratší cesta, jakmile víte, co děláte:
rename "s/\d{4}/2503/" file*
To jednoduše odpovídá prvním 4 číslům a vymění je za ta, která jste zadali.
A testovací postroj (-vn
znamená být podrobný, ale ne dělat cokoli) pomocí názvů souborů:
$ rename "s/\d{4}/2503/" file* -vn file0901201437404.p renamed as file2503201437404.p file0901201438761.p renamed as file2503201438761.p file1003201410069.p renamed as file2503201410069.p file2602201409853.p renamed as file2503201409853.p file2602201410180.p renamed as file2503201410180.p
Komentáře
- Poznámka že se jedná o přejmenování Perlu na Debian a jeho deriváty (Ubuntu, Mint,…). V jiných distribucích Linuxu je
rename
úplně jiný nástroj pro přejmenování souborů (který Debian dodává jakorename.ul
). - Pokud váš distribuční nedostatek takového nástroje chybí, podívejte se na odpověď @Michael Campbell. Myslím, že každá distribuční náhrada je výchozí
rename
jako debian.
Odpověď
To by mělo stačit:
for f in file*; do mv $f ${f/${f:4:8}/25032014}; done
Nahradí řetězec mezi 4. a 12. znakem řetězcem „25032014“.
Komentáře
- toto
for f in file*; do mv $f ${f/${f:4:4}/2503}; done
také funguje. - To ' je hezké. Pokud chcete pouze pravidelně nahradit slovo od slova, funguje to jako sed. např.
for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
- @Eric – vaši odpověď jsem zveřejnil jako alternativu, protože si myslím, že ' je jasnější a elegantnější . Pokud to také chcete zveřejnit jako odpověď – já ' smažu můj. Děkuji!
- Proč chybí dvojité uvozovky ?
- Dává mi chybu: " mv: target ' FILE_NAME ' není adresář "
Odpověď
toto je opravdu @Ericova odpověď shora – ale je to elegantní odpověď, takže Znovu to zveřejňuji jako správnou odpověď, abych na ni upozornil.
for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done
Odpovědět
ptrn="file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p" path=/dir ( set -- "${path}/"${ptrn} ; for f ; do { echo "mv ${path}/${f} \ ${path}/file25032014${f#2014}" } ; done )
To by mělo stačit. Poznámka – nemám ve zvyku předávat hromadné příkazy mv – jak je napsáno, je to jen ozvěna. Vy“ Budu to muset vyřešit dříve, než to bude fungovat.
Odpovědět
Jednoduchý nativní způsob, jak to udělat bez opakování, s procházení adresáře :
find -type f | xargs -I {} mv {} {}.txt
Bude přejmenován každý soubor na místě.
A pod dílem příklad s paralelizací :
find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}"
Komentáře
- Byl to první snadný přístup k lepšímu řešení. Pokud chcete funkční příkaz, proveďte:
-
find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
odpověď
Pokud zjistíte, že toho děláte hodně, vyhledejte „rename.pl“. Je to perlový skript, ale umožňuje vám jednoduše jej nakrmit perlovým kódem (například jako /// výraz) a na základě tohoto výrazu nebo kódu provede hromadné přejmenování.
Existuje základní verze zde: http://stackoverflow.org/wiki/Rename.pl , ale kolem sítě se pohybují i jiné verze. Je to už věky a věky a věky.
*
je?