2010-12-22 28 views
37

Mam wiele plików z rozszerzeniem .txt. Jak usunąć rozszerzenie .txt dla wielu plików w systemie Linux?Linux: usuń rozszerzenia plików dla wielu plików

stwierdziliśmy, że

rename .old .new *.old 

substytuty .old przedłużacz do .new

Również chcę to zrobić dla plików w podfolderach.

Odpowiedz

59

rename jest nieco niebezpieczne, gdyż zgodnie z jego ręcznym stronie:

przemianowania będzie zmieniać nazwy plików określone przez zastąpienie pierwszego wystąpienie od ...

Zrobi to złą rzecz z takimi nazwami plików jak c.txt.parser.y.

Oto rozwiązanie przy użyciu find i bash:

find -type f -name '*.txt' | while read f; do mv "$f" "${f%.txt}"; done 

Pamiętaj, że pęknie, jeśli nazwa pliku zawiera znak nowej linii (rzadko, ale nie niemożliwe).

Jeśli masz GNU znaleźć, jest to bardziej solidne rozwiązanie:

find -type f -name '*.txt' -print0 | while read -d $'\0' f; do mv "$f" "${f%.txt}"; done 
+1

To prawda w odniesieniu do 'util-linux-ng' wersji' rename', ale wersja skryptowa Perla może zrobić 'rename 's/.txt $ //' * .txt' –

+0

dla mnie zmienić nazwę 's/.txt $ // "* .txt nie zadziałało – rp101

+1

brakuje ci bieżącego". " jeśli chodzi o lokalizację, w której chcesz uruchomić. może to jest mój wariant wyszukiwania osx, lub moja ścieżka nie jest poprawnie ustawiona – bgs

10

Możesz jawnie przekazać pusty ciąg jako argument.

rename .old '' *.old

I z podfolderów, find . -type d -exec rename .old '' {}/*.old \;. {} jest substytutem wpisu znalezionego za pomocą find, a \; kończy listę argumentów dla polecenia podanego po -exec.

1

Dla podfolderów:

for i in `find myfolder -type d`; do 
    rename .old .new $i/*.old 
done 
+2

Może to powodować problemy, jeśli nie jest to nazwa folderu z miejsca w nim. – robert

15

Używam tego:

find ./ -name "*.old" -exec sh -c 'mv $0 `basename "$0" .old`.new' '{}' \; 
+0

dziękuję, nie znałem tej składni, i działa również na MacOSX (który nie ma natywnej 'rename'). – Utopik

+0

działa to świetnie pod Windows Git Bash, dzięki! – RaptoX

+0

Powinieneś dodać dirname w przypadku, gdy cel znajduje się w podfolderze: find ./ -name "* .old" -exec sh -c 'mv $ 0 'dirname" $ ​​0 "'/'basename" $ ​​0 ".old' .Nowy' '{}' \; –

13

wersja Perl przemianowania może usunąć rozszerzenie następująco:

rename 's/\.txt$//' *.txt 

Można to połączyć z findem, aby również wykonywać podfoldery.

1

w rybach, można zrobić

for file in *.old 
     touch (basename "$file" .old).new 
end 
3

w przypadku, gdy pomaga, oto jak to zrobić z zsh:

for f in ./**/*.old; do 
    mv "${f}" "${f%.old}" 
done 

${x%pattern} konstrukt w zsh usuwa najkrótszą wystąpienie pattern u koniec $x.Tutaj jest wydobywane jako funkcję:

function chgext() { 
    local srcext=".old" 
    local dstext="" 
    local dir="." 

    [[ "$#" -ge 1 ]] && srcext="$1" 
    [[ "$#" -gt 2 ]] && dstext="$2" dir="$3" || dir="${2:-.}" 

    local bname='' 
    for f in "${dir}"/**/*"${srcext}"; do 
     bname="${f%${srcext}}" 
     echo "${bname}{${srcext} → ${dstext}}" 
     mv "${f}" "${bname}${dstext}" 
    done 
} 

Zastosowanie:

chgext 
chgext src 
chgext src dir 
chgext src dst dir 

Where `src` is the extension to find (default: ".old") 
     `dst` is the extension to replace with (default: "") 
     `dir` is the directory to act on (default: ".") 
Powiązane problemy