【问题标题】:change lowercase file names to uppercase with awk ,sed or bash使用 awk 、sed 或 bash 将小写文件名更改为大写
【发布时间】:2017-12-28 19:06:14
【问题描述】:

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

您的帮助将不胜感激

aaaa.txt
vvjv.txt
acfg.txt

想要的输出

AAAA.txt
VVJV.txt
ACFG.txt

【问题讨论】:

  • 1.我使用这些技巧来更改我有趣的文件名,使用 bash 单行:for i in ./*.*;做 mv "$i" "$(echo "$i" | tr '[:?=&]' '[_]')";完毕 ; 2.交叉引用fyi来处理奇怪的unicode字符:stackoverflow.com/questions/3011569/…

标签: bash sed awk


【解决方案1】:

前言:

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

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

如果您确实关心扩展的大小写,那么您应该知道有不止一种方法可以做到这一点 (TIMTOWTDI)。就个人而言,我认为这里列出的 Perl 解决方案可能是 Linux 下最简单、最灵活的解决方案。如果您有多个文件扩展名,只需指定您希望保持不变的数字。 BASH4 解决方案也是一个很好的解决方案,但您必须愿意多次编写扩展名,或者使用另一个变量来存储它。但是,如果您需要严重的可移植性,那么我建议使用八进制的这个答案中的最后一个解决方案。某些版本的 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

【讨论】:

  • n.b. sed 解决方案与 Mac/Darwin/BSD(非 Linux?)不兼容 sed
  • @Orwellophile:GNU sed 不是 BSD sed。 BSD 是 Linux,就像 GNU 是 Linux。
  • 它也不适用于 Solaris。 (那是 SYSV)。但是你的更正被注意到了。它不适用于非 GNU 版本的 sed
  • @Orwellophile:更正?差不多两年前我就陈述了这个事实。如果您有一个非 GNU 系统,那么您还有其他更严重的问题,而不仅仅是文件名的情况。
【解决方案2】:

一般来说,小写/大写修改经常使用“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/' *

【讨论】:

    【解决方案3】:

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

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

    \U 大写直到\E,参见perlreref(1)。如果您对输出感到满意,请删除 -n。

    【讨论】:

    • 您可以添加 ^ 和 $ 锚点,并明确要求 '.',因此匹配不取决于正则表达式部分是贪婪还是懒惰;只是让它更具可读性恕我直言。
    • 这更符合 OP 的要求。我已添加您的建议
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      重击:

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

      【讨论】:

        【解决方案6】:
        for f in *.txt; do
          mv "$f" "`tr [:lower:] [:upper:] <<< "${f%.*}"`.txt"
        done
        

        【讨论】:

        • 这将大写“txt”扩展名。此外,对于 bash,请使用此处的字符串:tr [:upper] [:lower:] &lt;&lt;&lt; "$f"
        • @glennjackman 好点。 ${f%.*} 应该注意这一点。固定。
        【解决方案7】:

        一种更简单、轻量且可移植的方法是:

        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)。

        【讨论】:

          【解决方案8】:

          简单地使用(在终端上):

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

          【讨论】:

            【解决方案9】:

            这可能对你有用(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'
            

            【讨论】:

              【解决方案10】:
              for i in *.jar; do mv $i `echo ${i%} | tr [:upper:] [:lower:]`; done;  
              

              这对我有用。

              【讨论】:

                猜你喜欢
                • 2022-01-27
                • 2021-06-02
                • 2010-09-25
                • 2011-07-21
                • 2020-01-03
                • 1970-01-01
                • 2014-07-24
                • 2011-12-02
                • 1970-01-01
                相关资源
                最近更新 更多