Masowa zmiana nazwy, zmiana prefiksu

53

Jak mogę zbiorczo zastąpić prefiks dla wielu plików?

Mam wiele plików takich jak

  • TestSRConnectionContext.h
  • TestSRConnectionContext.m

Chciałbym zmienić je wszystkie na

  • CLConnectionContext.h
  • CLConnectionContext.m

Jak mam to zrobić?

ErikTJ
źródło

Odpowiedzi:

38
for name in TestSR*
do
    newname=CL"$(echo "$name" | cut -c7-)"
    mv "$name" "$newname"
done

Wykorzystuje to podstawienie polecenia bash do usunięcia pierwszych 6 znaków z wejściowej nazwy pliku przez cut, poprzedza CLwynik i zapisuje go w $newname. Następnie zmienia nazwę starej nazwy na nową. Odbywa się to na każdym pliku.

cut -c7-określa, że ​​tylko znaki po indeksie 7 powinny być zwracane z danych wejściowych. 7-oznacza zakres rozpoczynający się od indeksu 7 bez końca; to znaczy do końca linii.

Wcześniej korzystałem cut -b7-, ale -cpowinienem go używać do obsługi kodowania znaków, które mogą mieć wiele bajtów na znak, np. UTF-8.

mrb
źródło
Dzięki, teraz też to mam. Oznaczenie jako odpowiedź. Thx
ErikTJ
Działa to dobrze, dzięki. Czy możesz wyjaśnić, co robi -b7-? Czy to odniesienie do listy bajtów? ss64.com/bash/cut.html
imjared
@imjared Zaktualizowałem odpowiedź o więcej szczegółów.
mrb
56

Powiedziałbym, że najprościej jest po prostu użyć renamepolecenia, które jest wspólne w wielu dystrybucjach Linuksa. Istnieją dwie popularne wersje tego polecenia, więc sprawdź jego stronę podręcznika, aby znaleźć, którą masz:

## rename from Perl (common in Debian systems -- Ubuntu, Mint, ...)
rename 's/^TestSR/CL/' *

## rename from util-linux-ng (common in Fedora systems, Red Hat, CentOS, ...)
rename TestSR CL *

Jeśli chcesz używać wersji z util-linux-ng w systemie Debian, jest ona dostępna pod nazwą rename.ul

carandraug
źródło
7
Zastrzeżenie: wiele wersji renameistnieje na wolności. Sprawdź renamedokumentację lokalną, aby dowiedzieć się, jak korzystać z własnej .
jw013,
Aby usunąć alias, wykonajrename TestSR '' *
Bsienn
hmm ... rename "\<pre\>" "" *->Unterminated <> operator at (user-supplied code).
Flash Thunder,
32

Rozszerzenie parametrów powłoki wystarcza do takich prostych transformacji. Podstawianie poleceń jest mniej wydajne ze względu na konieczność odrodzenia dodatkowych procesów (dla samego podstawienia polecenia i cut/ sed).

for f in TestSR*; do mv "$f" "CL${f#TestSR}"; done
jw013
źródło
Objaśnienie: TestSR*znajdzie pliki, CL${f#TestSR}będzie nową nazwą. Rzeczy po tekście #zostaną zastąpione nazwą pliku ( f).
Joe Eifert
4

Oto jeden ze sposobów:

ls *.{h,m} | while read a; do n=CL$(echo $a | sed -e 's/^Test//'); mv $a $n; done
  • ls *.{h,m} -> Znajdź wszystkie pliki z rozszerzeniem .h lub .m
  • n=CL -> Dodaj prefiks CL do nazwy pliku
  • sed -e 's/^Test//' -> Usuwa przedrostek testowy z nazwy pliku
  • mv $a $n -> Wykonuje zmianę nazwy
Eric
źródło
3

Możesz spróbować z:

for i in TestSR*; do mv ${i} ${i/#TestSR/CL}; done

Aby man bashuzyskać szczegółowe informacje, patrz (sekcja „Rozszerzanie parametrów”).

Francesco Turco
źródło
1

Cóż, nie było tak trudne, jak myślałem.

$ for f in TestSR*.m; do mv $f CL$(echo $f | cut -c7-); done;
$ for f in TestSR*.h; do mv $f CL$(echo $f | cut -c7-); done;
ErikTJ
źródło
1
Jeśli pomoże Ci to w przyszłości, nie musisz powtarzać poleceń dla swoich dwóch wzorów; można użyć (na przykład): for f in TestSR*.[mh], for f in TestSR*.{m,h}, for f in TestSR*.m TestSR*.h.
mrb
1

Jeśli potrzebujesz czegoś bardziej zgubnego, możesz to zrobić

perl -e 'for(@ARGV) { rename($_, $n) if( ($n = $_ ) =~ s/^TestSR/CL/) }' *
użytkownik1146332
źródło