Jakie jest dobre polecenie do usuwania spacji, łączników i znaków podkreślenia ze wszystkich plików w katalogu lub wybranych plików?
Używam następującego polecenia z niestandardowymi działaniami Thunar, aby spowolnić nazwy plików:
for file in %N; do mv "$file" "$(echo "$file" | tr -s ' ' | tr ' A-Z' '-a-z' | tr -s '-' | tr -c '[:alnum:][:cntrl:].' '-')"; done
Ale to polecenie zastępuje spacje tylko myślnikami / myślnikami i małymi literami.
Użyłem następującego polecenia w terminalu, aby usunąć spacje z tysięcy nazw plików w folderze, i zadziałało to dość szybko:
rename "s/ //g" *
Ponownie usuwa tylko spacje, a nie łączniki / myślniki i podkreślenia.
Idealnie nie chcę spacji, myślników / myślników i podkreślników w moich nazwach plików. Byłoby wspaniale, gdyby komenda mogła być używana z niestandardowymi akcjami Thunar dla wybranych plików.
shell-script
files
rename
użytkownik8547
źródło
źródło
rename -i "s/[-_ ]//g" *
echo $file | sed -e 's/[ _-]//g'
; gotoweOdpowiedzi:
Ta wersja
rename
dołączona doperl
pakietu obsługuje wyrażenia regularne:Alternatywnie,
-i
Flaga będzie makerename
skorzystać z trybu interaktywnego, co skłoniło jeśli cel już istnieje, zamiast nadpisywania milczeniu.Nazwa Perla jest czasem nazywana
prename
.Zmiana nazwy Perla kontra zmiana nazwy util-linux
W systemach podobnych do Debiana zmiana nazwy perla wydaje się być domyślna i powyższe polecenia powinny po prostu działać.
W niektórych dystrybucjach
rename
narzędzie z util-linux jest domyślne. To narzędzie jest całkowicie niezgodne z Perlemrename
.Wszystko: najpierw sprawdź, czy Perl
rename
jest dostępny pod tą nazwąprename
.Debian: Zmiana nazwy Perla powinna być domyślna. Jest również dostępny jako
prename
. Plikrename
wykonywalny jest jednak pod kontrolą/etc/alternatives
i dlatego mógł zostać zmieniony na coś innego.archlinux: Uruchom,
pacman -S perl-rename
a polecenie jest dostępne jakoperl-rename
. Aby uzyskać wygodniejszą nazwę, utwórz alias. (Porada: ChiseledAbs)Mac OSX Według tej odpowiedzi ,
rename
może być zainstalowany na OSX używając homebrew poprzez:Bezpośrednie pobieranie:
rename
jest również dostępne w Perl Monks:źródło
rename
mówisz. Ten z util-linux -2.24.2-1.fc20.x86_64 nie obsługuje wyrażeń regularnych.rename
, której używał PO, wygląda jakperl
wersja, a nieutil-linux
wersja.rename
strona podręcznika użytkownika dla wersji util-linux . W każdym razie, oprócz tej notatki, ważną rzeczą jest to, że OP otrzymał swoją odpowiedź (a ty głos ode mnie :-D).pacman -S perl-rename
więc myślę, że możesz alias.Zastąpiłbym wszystkie te
tr
polecenia poleceniemsed
podstawienia, np .:źródło
Nie licząc
mv
, tak naprawdę wcale nie potrzebujesz do tego zewnętrznego procesu - możesz po prostu poofać .Mimo to oznacza to
mv
wywołanie na plik, a więc prawdopodobnierename
lepiej. Chociaż powinno działać podane tylko POSIXmv
w$PATH
i POSIX powłoki.Wymyśliłem do tego coś w rodzaju szalonego dema. Zestaw testowy jest generowany jak:
Po pierwsze, jako pierwszy potwierdzę, że powyższe polecenie daje wyniki, które można łatwiej uzyskać innymi sposobami. Ale inne środki prawdopodobnie nie pokazałyby równie dobrze, co można by zrobić z
$IFS
odrobiną (chorej) wyobraźni.Pierwszy bit jest więc dość prosty:
tee
usuwa 5 kopii danych wejściowych - heredocument o nazwieCGEN
dd
blokuje wprowadzanie nowego wiersza po 90 bajtów na blok i potoki, które ...sed
łączy 2 z tych bloków na dwóch\n
znakach ewline,'
pojedynczo cytuje wyniki i przygotowuje ciąg znakówtouch --
dla każdego cyklu wiersza przed odpływem do ...sh
który następnie wykonuje wszystkie dane wejściowe jako polecenia powłoki#CGEN
Nieco chociaż ... no, krótko ...na dole
printf
wydrukowano 252 0snastępny od ostatniego otrzymuje 252
''
argumentów o pustym łańcuchu i dla każdego wypisuje zawartość znaku$n
następującego po nim" $i "
eval
interpretuje argumenty następnegoprintf
przed wydrukowaniem wyników tej interpretacji jako liczby ósemkowe poprzedzone 2 ukośnikami odwrotnymiostatni
printf
wypisuje wartości bajtów dla tych liczb ósemkowych naraz, po których następuje łańcuch-_ ---___
dla każdej pary$n
jest inicjowany do równania, które będzie zwiększane$i
o jeden dla każdej oceny, z wyjątkiem tego, że pomija wartości 10, 39 lub 47 - (które są odpowiednio\n
ewline,'
pojedynczym cudzysłowem i/
ukośnikiem dziesiętnym ASCII)Rezultatem końcowym jest katalog zawierający wiele naprawdę brzydkich nazw plików zawierających każdy bajt w moim zestawie znaków od 1 do 255, z wyjątkiem pojedynczego cudzysłowu (pomijanego tylko w celu uniknięcia jeszcze jednej
sed s///
instrukcji) i/
ukośnika. Te nazwy plików wyglądają tak:Teraz uzyskam trochę danych na temat tych plików:
WYNIK
Ok. Teraz wreszcie do działania:
WYNIK
Sukces! Możesz przekonać się sam:
źródło
IFS
+printf
set -- 'some arbitrary' args; eval printf '"%s\n"' "$(IFS=0; printf ' "$@" %s' $(printf %025d))"
new="$(IFS=" -_"; printf %s $1)"
rozwidla podpowłokę (z wyjątkiem ksh93) i ma problemy z tailingiem nowych linii. Inną opcją jest użycieIFS=' -_'; set -- $1; IFS=; new="$*"
(i zmiana pętli while na pętlę for)[ -e x ]
zwróci false, jeślix
jest dowiązaniem symbolicznym do nieistniejącego lub niedostępnego pliku.jeśli masz perla, zwykle masz nazwę. możesz to zrobić:
i pokaż, jak napisany jest ten skrypt:
Ten skrypt nie obsługuje flagi -i (jest to wersja w moim systemie), ale może twój obsługuje. Co z argumentami. Pierwszy to wyrażenia regularne w formacie PCRE, działa jak filtr, modyfikuje nazwę wejściową do nazwy wyjściowej. Lista nazw wejściowych podanych przez gwiazdkę „*”. na przykład:
w rzeczywistości „*” można rozwinąć do:
Gdy masz naprawdę duże pliki, jesteś w pułapce. shell rozszerzy twoją linię dłużej niż system akceptuje. możesz obejść to za pomocą funkcji find lub xargs. używanie „znajdź” jest problemem, ponieważ zmiana nazwy będzie wywoływana wiele razy równa liczbie plików w katalogu. lepiej użyj xargs z opcją -r. jedna zmiana nazwy połączenia modyfikuje wiele plików. na przykład:
ostatni problem, co to znaczy:
jest to wyrażenie regularne do modyfikowania nazw. po pierwszym „/” jest spacją. jest to wykrywane i zastępowane ciągiem znaków po drugim „/”. Ale jest pusty ciąg zakończony trzecim '/', następnie spacja jest zastępowana przez nic. Opcja „g” sprawia, że wyrażenie to się powtarza. wyrażenie przejdzie do wszystkich nazw od początku do końca i wykryje wszystkie spacje.
Ale co, jeśli masz znak tabulacji lub inny „biały” znak? istnieje zamiennik tych „\ s”. jakie inne niepotrzebne postacie? po prostu dodaj go do wyrażenia. Wszystkie zamykane za pomocą nawiasów, na przykład:
to wszystko. widzisz podobieństwo? Myślę, że powinieneś przeczytać Man Perlrequick i Man Perlretut, to wyjaśnia ci (mam nadzieję), jak działa wyrażenie regularne. w razie potrzeby możesz użyć polecenia zmiany nazwy we własnym skrypcie.
źródło
Następująca
sh
pętla powłoki usunie wszystkie spacje, podkreślenia i myślniki z nazw plików w bieżącym katalogu, uważając, aby nie zastąpić istniejących plików:Za
bash
iksh
będąc nieco bardziej gadatliwym z logiką:Usuń,
echo
gdy masz pewność, że robi to, co chcesz.tr
Komenda delete (-d
) dowolny znak w danym zestawie znaków (' _-'
). Ważne jest, aby mieć myślnik na samym początku lub na końcu zestawu, inaczej będzie interpretowany jako zakres znaków.źródło