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
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
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
n.b. Rozwiązanie sed nie jest kompatybilne z Mac/Darwin/BSD (nie-Linux?) * sed * – Orwellophile
@Orwellophile: GNU sed nie jest BSD sed. BSD to Linux, tak jak GNU to Linux. – Steve
Nie działa również z Solaris. (To jest SYSV). Ale twoja korekta jest zanotowana. Nie działa z wersjami nieseksualnymi ** sed ** – Orwellophile
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/' *
for f in *.txt; do
mv "$f" "`tr [:lower:] [:upper:] <<< "${f%.*}"`.txt"
done
To zamieni na wielkie litery rozszerzenie "txt". Ponadto, w bashu, użyj tu-string: 'tr [: upper] [: lower:] <<<" $ f "' –
@glennjackman Dobra uwaga. '$ {f%. *}' powinien się tym zająć. Naprawiony. –
Bash 4 parametr ekspansja może wykonywać przypadek zmienia:
for i in *.txt; do
i="${i%.txt}"
mv "$i.txt" "${i^^?}.txt"
done
bash:
for f in *.txt; do
no_ext=${f%.txt}
mv "$f" "${no_ext^^}.txt"
done
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'
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.
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. –
To lepiej pasuje do tego, co chce OP. Dodałem Twoje sugestie – Thor
Ł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.
Wystarczy użyć (na terminalu):
for i in *.txt; do mv $i `echo ${i%.*} | tr [:lower:] [:upper:]`.txt; done;
for i in *.jar; do mv $i `echo ${i%} | tr [:upper:] [:lower:]`; done;
to działa na mnie.
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