2012-09-17 16 views
5

chciałbym zmienić małe nazw plików na wielkie litery z awk/sed/bashzmienić małe nazw plików na wielkie litery z awk, sed lub bash

twoja pomoc będzie mile widziane

aaaa.txt 
vvjv.txt 
acfg.txt 

pożądane wyjście

AAAA.txt 
VVJV.txt 
ACFG.txt 
+0

1.I użyłem tych wskazówek, aby zmienić moje śmieszne nazwy plików za pomocą bash one-liner: for i in ./*.*; do mv "$ i" "$ (echo" $ i "| tr '[:? = &]" [_] ")"; Gotowe ; 2. Porównywalne fyi do obsługi nawet dziwnych znaków unicode: http://stackoverflow.com/questions/3011569/how-do-i-convert-filenames-from-unicode-to-ascii – AnneTheAgile

Odpowiedz

15

WSTĘP:

Jeśli nie dbają o przypadku rozszerzeń, wystarczy użyć narzędzia „tr” w pętli powłoki:

for i in *.txt; do mv "$i" "$(echo "$i" | tr '[a-z]' '[A-Z]')"; done 

Jeśli dbasz o przypadku rozszerzeń, to należy mieć świadomość, że istnieje więcej niż jeden sposób zrobienia tego (TIMTOWTDI). Osobiście uważam, że wymienione tutaj rozwiązanie Perl jest prawdopodobnie najprostszym i najbardziej elastycznym rozwiązaniem pod Linuksem. Jeśli masz wiele rozszerzeń plików, po prostu podaj numer, który chcesz zachować bez zmian. Roztwór jest również bardzo dobry, ale musisz być gotowy do wypisania rozszerzenia kilka razy lub alternatywnie użyć innej zmiennej do przechowywania. Ale jeśli potrzebujesz poważnego przenoszenia, polecam ostatnie rozwiązanie w tej odpowiedzi, które używa ósemków. Niektóre smaki Linuksa są również dostarczane z narzędziem o nazwie o zmianie nazwy, które również warto wypróbować. Jego użycie będzie się różnić od dystrybucji do dystrybucji, więc wpisz man rename, aby uzyskać więcej informacji.

ROZWIĄZANIA:

Stosując Perl:

# single extension 
perl -e 's/\.[^\.]*$/rename $_, uc($`) . $&/e for @ARGV' *.txt 

# multiple extensions 
perl -e 's/(?:\.[^\.]*){2}$/rename $_, uc($`) . $&/e for @ARGV' *.tar.gz 

Stosując BASH4:

# single extension 
for i in *.txt; do j="${i%.txt}"; mv "$i" "${j^^}.txt"; done 

# multiple extensions 
for i in *.tar.gz; do j="${i%.tar.gz}"; mv "$i" "${j^^}.tar.gz"; done 

# using a var to store the extension: 
e='.tar.gz'; for i in *${e}; do j="${i%${e}}"; mv "$i" "${j^^}${e}"; done 

Stosując GNU awk:

for i in *.txt; do 

    mv "$i" $(echo "$i" | awk '{ sub(/.txt$/,""); print toupper($0) ".txt" }'); 
done 

Stosując GNU sed:

for i in *.txt; do 

    mv "$i" $(echo "$i" | sed -r -e 's/.*/\U&/' -e 's/\.TXT$/\u.txt/'); 
done 

Stosując BASH3.2:

for i in *.txt; do 

    stem="${i%.txt}"; 

    for ((j=0; j<"${#stem}"; j++)); do 

     chr="${stem:$j:1}" 

     if [[ "$chr" == [a-z] ]]; then 

      chr=$(printf "%o" "'$chr") 

      chr=$((chr - 40)) 

      chr=$(printf '\'"$chr") 
     fi 

     out+="$chr" 
    done 

    mv "$i" "$out.txt" 

    out= 
done 
+0

n.b. Rozwiązanie sed nie jest kompatybilne z Mac/Darwin/BSD (nie-Linux?) * sed * – Orwellophile

+0

@Orwellophile: GNU sed nie jest BSD sed. BSD to Linux, tak jak GNU to Linux. – Steve

+0

Nie działa również z Solaris. (To jest SYSV). Ale twoja korekta jest zanotowana. Nie działa z wersjami nieseksualnymi ** sed ** – Orwellophile

9

Ogólnie w przypadku małych liter/wielkich liter często używane jest narzędzie "tr" (translate characters), które pochodzi z zestawu narzędzi wiersza poleceń używanych do zastępowania znaków.

dtpwmbp:~ pwadas$ echo "xxx" | tr '[a-z]' '[A-Z]' 
XXX 
dtpwmbp:~ pwadas$ 

Do zmiany nazwy plików służy także program "zmień nazwę" dostarczany z perl (zmiana nazwy użytkownika).

SYNOPSIS 
     rename [ -v ] [ -n ] [ -f ] perlexpr [ files ] 

DESCRIPTION 
     "rename" renames the filenames supplied according to the rule specified as the first argument. The perlexpr argument is a Perl expression which is expected to modify the $_ string in 
    Perl for at least some of the filenames specified. If a given filename is not modified by the expression, it will not be renamed. If no filenames are given on the command line, 
    filenames will be read via standard input. 

    For example, to rename all files matching "*.bak" to strip the extension, you might say 

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

    To translate uppercase names to lower, you'd use 

      rename 'y/A-Z/a-z/' * 
1
for f in *.txt; do 
    mv "$f" "`tr [:lower:] [:upper:] <<< "${f%.*}"`.txt" 
done 
+0

To zamieni na wielkie litery rozszerzenie "txt". Ponadto, w bashu, użyj tu-string: 'tr [: upper] [: lower:] <<<" $ f "' –

+0

@glennjackman Dobra uwaga. '$ {f%. *}' powinien się tym zająć. Naprawiony. –

1

Bash 4 parametr ekspansja może wykonywać przypadek zmienia:

for i in *.txt; do 
    i="${i%.txt}" 
    mv "$i.txt" "${i^^?}.txt" 
done 
1

bash:

for f in *.txt; do 
    no_ext=${f%.txt} 
    mv "$f" "${no_ext^^}.txt" 
done 
0

To może pracować dla Ciebie (GNU sed):

printf "%s\n" *.txt | sed 'h;s/[^.]*/\U&/;H;g;s/\(.*\)\n/mv -v \1 /' | sh 

lub prościej:

printf "%s\n" *.txt | sed 'h;s/[^.]*/\U&/;H;g;s/\(.*\)\n/mv -v \1 /e' 
4

Sugerowałbym użyciu rename, jeśli chcesz tylko wielkie litery nazwy pliku, a nie przedłużacz, należy użyć coś takiego:

rename -n 's/^([^.]*)\.(.*)$/\U$1\E.$2/' * 

\U uppercases wszystko aż \E zobacz perlreref(1). Usuń -n, gdy jesteś zadowolony z wyjścia.

+0

Możesz dodać kotwice^i $ i jawnie wymagać ".", Więc dopasowanie nie zależy od tego, czy sekcja regex jest chciwa czy leniwy; po prostu czyni to czytelniejszym IMHO. –

+0

To lepiej pasuje do tego, co chce OP. Dodałem Twoje sugestie – Thor

1

Łatwiejszy, lekki i przenośny podejście byłoby:

for i in *.txt 
do 
    fname=$(echo $i | cut -d"." -f1 | tr [a-z] [A-Z]) 
    ext=$(echo $i | cut -d"." -f2) 
    mv $i $fname.$ext 
done 

To działa na niemal każdej wersji bash ponieważ używamy najczęstsze zewnętrznych narzędzi (wytnij, tr) znajdują się na każdym smaku Unix.

1

Wystarczy użyć (na terminalu):

for i in *.txt; do mv $i `echo ${i%.*} | tr [:lower:] [:upper:]`.txt; done; 
0
for i in *.jar; do mv $i `echo ${i%} | tr [:upper:] [:lower:]`; done; 

to działa na mnie.

Powiązane problemy