Zmień nazwę grupy plików za pomocą jednego polecenia


38

Jeśli mam grupę plików z rozszerzeniem .htm, jak mogę zmienić ich nazwy na .html?

mv *.htm *.html

nie działa.


Tylko ze względu na kompletność, ren *.htm *.htmlbędzie działać w systemie Windows.
Brian Burns

Odpowiedzi:


50

Lub możesz użyć czystej bash ... (oprócz mv, to znaczy ...)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

i unikaj nieprzyjemnych rzeczy basename. ;)

Bash ma bogaty zestaw zmiennych opcji ekspansji. Zastosowany tutaj „%” usuwa najmniejszy zgodny sufiks z wartości zmiennej. Wzór jest wzorem globalnym, więc ${file%.*}też by działał. Operator „%%” usuwa największy pasujący sufiks i jest wymienny w powyższym przykładzie, ponieważ wzorzec jest ustalony, ${file%%.*}.htmlzmieniłby abhtm w a.html.

Zobacz sekcję zmiennego podstrona strony podręcznika bash, aby uzyskać więcej schludnych sztuczek. Jest wiele rzeczy, które można zrobić bezpośrednio w bash.


1
Zauważ też, że te rozszerzenia parametrów nie są ograniczone do bash . Są one dostępne na wszystkich powłokach Bourne'a ( sh , ksh , bash , zsh , dash , ash itp.). Rozszerzenia są częścią specyfikacji POSIX dla „Shell Command Language” i są wysoce przenośne.
Chris Johnsen

11

W nazwach plików nie powinno być spacji, znaków nowej linii ani innych białych znaków, ale ta wersja odpowiedzi freiheit obsługuje je. Używa również $()zamiast backticks dla czytelności wraz z innymi korzyściami.

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

Jeszcze lepiej - w specjalnym przypadku dodawania tylko do końca:

for file in *.htm
do
    mv "$file" "${file}l"
done

11

rename(1)to narzędzie Perla, które robi dokładnie to, co chcesz. W tym przypadku:

rename 's/\.htm$/.html/' *htm

lub jeśli używasz również podkatalogów

(wymaga Bash 4.0 i ustawienie globstar: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm


1
zmiana nazwy jest łatwiejsza, ale nie jest standardowym programem uniksowym; oryginalne pytanie nie określa, który unix. W niektórych miejscach wydaje się być „prename”.
freiheit,

2
renamepochodzi z perla, i w zasadzie każdy unix ma teraz perla.
TRS-80,

3
tak, ale nie każdy uniks zawiera programy pomocnicze, takie jak „zmiana nazwy”, kiedy wprowadzają perla do systemu. Na przykład w OSX nie ma „zmiany nazwy”.
freiheit

1
@William: Składnia podwójnej gwiazdki jest dostępna tylko w Bash 4 i nowszych wersjach i tylko wtedy, gdy jest włączona shopt -s globstar(domyślnie wyłączona). Ponadto Linux i Unix mają katalogi zamiast folderów.
Wstrzymano do odwołania.

6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Wypróbuj go ze związkiem echoprzed mvpierwszym razem.

Problem z oryginałem polega na tym, że „ mv *.htm *.html” ma *s obsługiwane przez powłokę, więc mvpolecenie po prostu wyświetla listę wszystkich plików .htm i .html w bieżącym katalogu. Innymi słowy, coś w stylu „ mv foo.htm bar.htm stuff.htm six.htm file.htm”. mv wie, jak obsługiwać więcej niż 2 argumenty, jeśli ostatni jest katalogiem.


1
Powinieneś zacytować „$ file”, aby obsłużyć spacje.
Richard Hoskins,

Twój opis pierwotnego problemu powinien być silniej podkreślony. To zachowanie interpretacji symboli wieloznacznych powłoki jest zaskakujące i nie jest intuicyjne dla kogoś pochodzącego z systemu Windows, a zrozumienie tego, co robi powłoka, wyjaśnia, dlaczego oryginalna aplikacja mvnie działa.
Greg Hewgill

3

Jeszcze inny przykład czystego basha z użyciem metody replace łańcucha.

for file in *.htm; do mv $file ${file/htm/html}; done

Extra - zastępuje wszystkie wystąpienia ciągu

for file in *.htm; do mv $file ${file//htm/html}; done



0

Pakiet util-linux-ng (w Fedorze) ma renamepolecenie podobne do polecenia wspomnianego przez TRS-80 . Możesz użyć tego w następujący sposób:

rename .htm .html *.html
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.