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

时间:2012-09-17 22:54:44

标签: bash sed awk

我想用awk / sed / bash

将小写文件名更改为大写

您的帮助将不胜感激

aaaa.txt
vvjv.txt
acfg.txt

期望的输出

AAAA.txt
VVJV.txt
ACFG.txt

10 个答案:

答案 0 :(得分: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

答案 1 :(得分: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/' *

答案 2 :(得分:4)

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

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

\U\E之前对所有内容进行大写,请参阅perlreref(1)。当您对输出感到满意时,请移除-n

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

击:

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

答案 6 :(得分: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)。

答案 7 :(得分:1)

只需使用(在终端上):

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

答案 8 :(得分: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'

答案 9 :(得分:0)

TabBar

这适合我。