使用awk,sed或bash将小写文件名更改为大写

问题描述 投票:5回答:10

我想用awk / sed / bash将小写文件名更改为大写

你的帮助将不胜感激

aaaa.txt
vvjv.txt
acfg.txt

期望的输出

AAAA.txt
VVJV.txt
ACFG.txt
bash sed awk
10个回答
17
投票

前言:

如果您不关心扩展的情况,只需在shell循环中使用'tr'实用程序:

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

如果您确实关心扩展的情况,那么您应该知道有多种方法可以做到(TIMTOWTDI)。就个人而言,我相信这里列出的Perl解决方案可能是Linux下最简单,最灵活的解决方案。如果您有多个文件扩展名,只需指定您希望保持不变的数字。 BASH4解决方案也是一个很好的解决方案,但你必须愿意写几次扩展,或者使用另一个变量来存储它。但是如果您需要严格的可移植性,那么我建议使用octals的答案中的最后一个解决方案。有些版本的Linux还附带了一个名为rename的工具,也可能值得一试。它的用法将从发行版到发行版不等,因此请输入man rename以获取更多信息。

解决方案:

使用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

使用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

使用GNU awk

for i in *.txt; do

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

使用GNU sed

for i in *.txt; do

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

使用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
投票
for i in *.jar; do mv $i `echo ${i%} | tr [:upper:] [:lower:]`; done;  

这对我有用。


9
投票

通常,对于小写/大写修改,经常使用“tr”(翻译字符)实用程序,它来自用于字符替换的命令行实用程序集。

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

此外,对于重命名文件,还有“重命名”实用程序,与perl(man rename)一起提供。

    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/' *

4
投票

我建议使用rename,如果你只想大写文件名而不是扩展名,请使用以下内容:

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

\U将所有内容改为\E,请参阅perlreref(1)。当你满意输出时删除-n


1
投票

Bash 4参数扩展可以执行大小写更改:

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

1
投票

庆典:

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

1
投票
for f in *.txt; do
  mv "$f" "`tr [:lower:] [:upper:] <<< "${f%.*}"`.txt"
done

1
投票

一种更简单,轻便和便携的方法是:

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

这几乎适用于BASH的每个版本,因为我们使用的是每种Unix风格上最常见的外部实用程序(cut,tr)。


1
投票

只需使用(在终端上):

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

0
投票

这可能适合你(GNU sed):

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

或更简单地说:

printf "%s\n" *.txt | sed 'h;s/[^.]*/\U&/;H;g;s/\(.*\)\n/mv -v \1 /e'
© www.soinside.com 2019 - 2024. All rights reserved.