2013-03-08 12 views
52

Używam tego polecenia, aby znaleźć pliki z danego wzorca, a następnie zmienić je na coś innegoznaleźć wzór w plikach i ich nazwy

find . -name '*-GHBAG-*' -exec bash -c 'echo mv $0 ${0/GHBAG/stream-agg}' {} \; 

Jak uruchomić to polecenie, widzę kilka wyjść jak ten

mv ./report-GHBAG-1B ./report-stream-agg-1B 
mv ./reoprt-GHBAG-0.5B ./report-stream-agg-0.5B 

Jednak na końcu, gdy uruchamiam ls, widzę stare nazwy plików.

+0

przepełnienie stosu jest witryną dla pytań programowania i rozwoju. To pytanie wydaje się być nie na temat, ponieważ nie chodzi o programowanie czy rozwój. Zobacz [Jakie tematy mogę tu zadać] (http://stackoverflow.com/help/on-topic) w Centrum pomocy. Być może lepszym rozwiązaniem będzie [Super użytkownik] (http://superuser.com/) lub [Unix i Linux Stack Exchange] (http://unix.stackexchange.com/). Zobacz także [Gdzie mogę zamieszczać pytania na temat Dev Ops?] (Http://meta.stackexchange.com/q/134306) – jww

+0

Lepsze pytanie dla większości osób, które google to https://stackoverflow.com/questions/1086502/rename-multiple-files-in-unix – tripleee

Odpowiedz

76

Powtarzasz polecenie "mv", a nie wykonujesz go. Zmień na:

find . -name '*-GHBAG-*' -exec bash -c 'mv $0 ${0/GHBAG/stream-agg}' {} \; 
+10

Dzięki za to rozwiązanie. Ale lepiej otaczaj te zmienne w '' 'jeśli masz' 'na nazwach plików.' Mv "0 $" "$ {0/GHBAG/stream-agg}" '. – erickb

+1

@erickb great catch =) – Kyle

+3

Nie miałem pojęcia możesz dokonywać podstawień na zmienne w bashie tak, jak to Fantastyczne! – Snorfalorpagus

34

Proponuję użyć polecenia rename do wykonania tego zadania. rename zmienia nazwy plików dostarczonych zgodnie z regułą określoną jako wyrażenie regularne Perl.

W tym przypadku można użyć:

rename 's/GHBAG/stream-agg/' *-GHBAG-* 
+0

Dzięki. Jest znacznie prostsze, ale grałem z 'exec' – mahmood

+0

Z pewnością' find' z '-exec' ma tę zaletę, że szuka rekursywnie w katalogu, który zmiana nazwy nie może, ale "zmiana nazwy" będzie szybsza, ponieważ nie będzie spawnować procesu dla każdego pojedynczego pliku, którego nazwa ma zostać zmieniona – anumi

+1

@anumi 'man find' pokazuje' -exec command {} + 'jako opcję do wykonania tylko jednej instancji we wszystkich Znalazłem pliki, chociaż nie wiem, czy jest to użyteczne w przykładzie z pierwotnego pytania: –

17

W odpowiedzi na komentarz anumi użytkownika, można w efekcie poszukiwań rekurencyjnie w dół katalogów dopasowując '**':

rename 's/GHBAG/stream-agg/' **/*-GHBAG-* 
+1

Próbowałem tego i działało tylko dla jednej ścieżki z kilku podkatalogów. 'znajdź. -name "*: *" 'nadal wyświetla listę plików po uruchomieniu' rename -v 's /:/- /' **/*: * ', a druga zmiana nazwy-run daje" _Nie taki plik lub directory_ "notify . (Debian 6) –

+1

zmiana nazwy nie jest uniwersalnym poleceniem unix. –

1

Działa to dla moje potrzeby, zastępując wszystkie pasujące pliki lub typy plików. Ostrzegamy, to jest bardzo chciwy wyszukiwania

# bashrc 
function file_replace() { 
    for file in $(find . -type f -name "$1*"); do 
    mv $file $(echo "$file" | sed "s/$1/$2/"); 
    done 
} 

będę zwykle uruchamiane z find . -type f -name "MYSTRING*" z wyprzedzeniem, aby sprawdzić mecze przed wymianą.

Na przykład:

file_replace "Slider.js" "RangeSlider.ts" 

renamed: packages/react-ui-core/src/Form/Slider.js -> packages/react-ui-core/src/Form/RangeSlider.ts 
renamed: stories/examples/Slider.js -> stories/examples/RangeSlider.ts 

lub rowu filetype aby jeszcze greedier

file_replace Slider RangeSlider 

renamed: packages/react-ui-core/src/Form/Slider.js -> packages/react-ui-core/src/Form/RangeSlider.js 
renamed: stories/examples/Slider.js -> stories/examples/RangeSlider.js 
renamed: stories/theme/Slider.css -> stories/theme/RangeSlider.css 
Powiązane problemy