Zmień nazwę plików, zwiększając liczbę w nazwie pliku

14

Mam katalog, który zawiera numerowane pliki obrazów, mniej więcej tak:

01.png
02.png
03.png
03.svg
04.png
05.png
06.jpg
07.png
08.png
09.png
09.svg
10.png

Czasami może istnieć wiele wersji pliku w różnych formatach (np. A pngoraz svgwersja 03i 09pliki powyżej), ale w przeciwnym razie liczby są kolejne. Zazwyczaj w każdym katalogu znajduje się 40–80 takich plików. Liczby odpowiadają kolejności, w jakiej te obrazy pojawiają się w manuskrypcie (dokument Word, ale to nie jest ważne). Nie ma innego sposobu na określenie kolejności obrazów.

Jeśli dodam nowy obraz do rękopisu, muszę umieścić kopię obrazu w tym katalogu z poprawną numeracją. Więc jeśli nowy obraz jest piąty w rękopisie, muszę zmienić nazwę plików w katalogu na to, aby zrobić dla niego miejsce:

01.png
02.png
03.png
03.svg
04.png
06.png
07.jpg
08.png
09.png
10.png
10.svg
11.png

Jaki jest najprostszy sposób z wiersza poleceń lub skryptu lub makra, aby ponownie numerować wszystkie pliki zaczynające się od określonej liczby? Mam standardową instalację Fedory Linux za pomocą bash.

robertc
źródło

Odpowiedzi:

11

Myślę, że to powinno wystarczyć:

#!/bin/bash

NEWFILE=$1

for file in `ls|sort -g -r`
do
    filename=$(basename "$file")
    extension=${filename##*.}
    filename=${filename%.*}

    if [ $filename -ge $NEWFILE ]
    then
        mv "$file" "$(($filename + 1))".$extension
    fi
done

Skrypt ma jeden parametr - numer twojego nowego obrazu.

PS. Umieść skrypt w innym katalogu niż twoje obrazy. W katalogu obrazów powinny znajdować się tylko obrazy nazwane w ten sposób, który opisałeś.

pbm
źródło
To wygląda obiecująco, spróbuję za kilka godzin, kiedy wrócę na laptopa.
robertc
Działa to tylko wtedy, gdy nazwa pliku nie jest poprzedzona
znakami nienumerycznymi
@mems OP wyraźnie stwierdza, że ​​nazwy plików zaczynają się od liczby
xhienne
2

Byłoby to łatwiejsze w Zsh, gdzie możesz użyć

  • On kwalifikator glob na mecze sortowanie malejące (i nużywać kolejności numerycznej, w przypadku nazwy plików nie wszyscy mają początkowych zer na tej samej szerokości);
  • (l:WIDTH::FILLER:) flaga rozszerzenie parametr w celu wypełnienia wszystkich numerów do tej samej szerokości (szerokości większej liczby).
break=$1   # the position at which you want to insert a file
setopt extended_glob
width=
for x in [0-9]*(nOn); do
  n=${x%%[^0-9]*}
  if ((n < break)); then break; fi
  ((++n))
  [[ -n $width ]] || width=${#n}
  mv $x ${(l:$width::0:)n}${x##${x%%[^0-9]*}}
done

W bash, oto skrypt, który zakłada, że ​​pliki są dopełniane do stałej szerokości (w przeciwnym razie skrypt nie zmieni nazwy odpowiednich plików) i pady do stałej szerokości (którą należy określić).

break=$1      # the position at which you want to insert a file
width=9999    # the number of digits to pad numbers to
files=([0-9]*)
for ((i=#((${#files}-1)); i>=0; --i)); do
  n=${x%%[^0-9]*}
  x=${files[$i]}
  if ((n < break)); then continue; fi
  n=$((n + 1 + width + 1)); n=${n#1}
  mv -- "${files[$i]}" "$n${x##${x%%[^0-9]*}}"
done
Gilles „SO- przestań być zły”
źródło
1

Dokładny problem jest omówiony w tym artykule . Pamiętaj, że musisz go zmodyfikować, aby obsługiwał formaty SVG i PNG, dodając drugi krok SN.

Jodie C.
źródło
Nie sądzę, że jest to dokładny problem, który zmienia numerację wszystkich obrazów za każdym razem. Chcę tylko przenumerować obrazy z określonego punktu.
robertc
1

Łatwiej:

touch file`ls file* | wc -l`.ext

Dostaniesz:

$ ls file*
file0.ext  file1.ext  file2.ext  file3.ext  file4.ext  file5.ext  file6.ext
Hugoren Martinako
źródło
Jak dodać wiodące zero dla 1-9? Pamiętaj również, że mogą istnieć dwa pliki 03.png i 03.svg.
robertc,
1

Wydaje się, że ostatnio nie ma zainteresowania tym pytaniem, ale jeśli ktoś się na niego natknie, istnieją tutaj trzy kwestie. Jednym z nich jest wybór plików do zmiany nazwy na podstawie kryteriów semantycznych (zakres nie jest leksykalny i nie można go określić za pomocą symboli wieloznacznych ani nawet wyrażeń regularnych - teoria automatów mówi, że jest to bardziej złożone niż NFA). Drugim jest, jak zmienić nazwę, modyfikując jej część. Trzecim jest, jak uniknąć kolizji nazw. Skrypt w Bash i wielu innych językach może dokonać tej konkretnej transformacji, ale większość z nas wolałaby nie pisać programu za każdym razem, gdy chcemy zmienić nazwę kilku plików. Z moim (darmowym i otwartym źródłem) rene.py możesz robić, co chcesz, ale potrzeba dwóch wywołań, aby uniknąć problemu kolizji nazw. Pierwszyrene ?.*/#7-80 %?.* Bzwiększa wszystkie nazwy w zakresie, dodając prefiks%, aby uniknąć istniejących nazw. Następnie rene %* *usuwa ten prefiks z plików, które go mają. Opisuję to na https://sourceforge.net/p/rene-file-renamer/discussion/examples/thread/f0fe8aa63c/

David McCracken
źródło