【问题标题】:Change extension of file using shell script使用 shell 脚本更改文件的扩展名
【发布时间】:2012-03-24 08:36:16
【问题描述】:

如何将目录中所有 *.dat 文件的扩展名更改为 *.txt。 Shell 脚本应将目录名称作为参数。能 将多个目录作为参数。打印命令日志 导致带有日期和时间戳的附加模式。

【问题讨论】:

标签: linux shell unix


【解决方案1】:

Batch File Rename By File Extension in Unix

# change .htm files to .html
for file in *.htm ; do mv $file `echo $file | sed 's/\(.*\.\)htm/\1html/'` ; done

# change .html files to .htm
for file in *.html ; do mv $file `echo $file | sed 's/\(.*\.\)html/\1htm/'` ; done

#change .html files to .shtml
for file in *.html ; do mv $file `echo $file | sed 's/\(.*\.\)html/\1shtml/'` ; done

#change .html files to php
for file in *.html ; do mv $file `echo $file | sed 's/\(.*\.\)html/\1php/'` ; done

所以 ==>

# change .dat files to .txt
for file in *.dat ; do mv $file `echo $file | sed 's/\(.*\.\)dat /\1txt/'` ; done

【讨论】:

  • mv $file ${file%.dat}.txt # 知道你的 shell 内置 cruft
  • 为什么不's/\.htm$/\.html/'
  • @Kaz,最好使用${file%%<EXT>},因为可能有all.html.files.tar.gz之类的东西
  • @Kaz ${file %.dat} 来自 bash,我不能使用 bash。 Pben 的答案更具交叉兼容性,这通常是我所需要的。
  • @SebastianGodelet 当 PAT 匹配固定长度的内容时,${VAR%PAT}${VAR%%PAT} 之间没有区别,例如文字文本 .dat。如果您的<EXT> 只是.html,则无论% 还是%%,它都不会匹配all.html.files.tar.gz
【解决方案2】:
#!/bin/bash
for d in $*; do
    for f in $(ls $d/*.dat); do
        echo $(date) $(mv -v $f ${f%.dat}.txt)
    done
done

在运行脚本时应该由shell完成输出重定向

省略参数有效性检查

【讨论】:

    【解决方案3】:

    简单脚本:

    #!/bin/bash
    
    if [ $# -lt 2 ] then
        echo "Usage `basename $0` <any number of directories space separated>"
        exit 85              # exit status for wrong number of arguments.
    fi
    
    for directories
    do
        for files in $(ls $directories/*.dat); do
            echo $(date) $(mv -v $files ${files%.dat}.txt)
        done
    done
    

    默认情况下,第一个 for 循环在 $@ 上循环,即传递的命令行参数。

    【讨论】:

      【解决方案4】:

      按照 Pben 的解决方案,如果你的文件名包含空格,你应该使用双引号给变量,如下所示:

      #remove the space in file name
      #example file name:19-014-0100.mp3 .mp3
      #result file name:19-014-0100.mp3
      $ for file in *.mp3 ; 
          do target=`echo "$file" | sed 's/ //g'`;
          echo "$target"; 
          mv "$file" "$target"; 
      done;
      
      #remove the duplicate file extension in file name
      #example file name:19-014-0100.mp3.mp3
      #result file name:19-014-0100.mp3
      $ for file in *.mp3 ; 
          do target=`echo "$file" | sed 's/\.mp3\.mp3$/.mp3/g'`;
          echo "$target"; 
          mv "$file" "$target"; 
      done;
      

      【讨论】:

        【解决方案5】:

        脚本,首先查找给定扩展名的名称。 它从名称中删除扩展名。然后添加反斜杠() 用于终端识别。

        然后执行“mv”命令。 这里的“.temp”文件夹用于向用户隐藏进程, 在 GUI 中。

        #!/bin/sh
        if [ $# -ne 3 ] 
        then
            echo "Usage:  ./script folder current_extension modify_extension"
            exit
        fi
        mkdir .temp
        find $1 -name "*.$2" > .temp/output_1 && sed "s/$2//" .temp/output_1 > .temp/output_2 && sed -e "s/[ \t]/\\\ /g" .temp/output_2 > .temp/output_3
        while read line
        do
            mv -v "$line""$2" "$line""$3"
        done < .temp/output_3
        rm -rf .temp
        

        输出文件保存在“.temp”文件夹中,之后“.temp”文件夹被删除。

        【讨论】:

          【解决方案6】:

          票数最高的答案对我来说并不适用。我可能做错了什么。我的场景是尝试创建一个具有原始名称但附加日期的文件,并将扩展名从 .xslx 更改为 .csv。这对我有用:

          csvname=`echo $xlsx |sed 's/\.xlsx//'`"-$now"`echo $xlsx | sed 's/\(.*\.\)xlsx/\.csv/'`
          

          因此,对于目录中的所有 .dat 文件(不添加日期),您可以运行如下内容:

          for i in *.dat
          do mv $i `echo $i |sed 's/\.dat//'``echo $i | sed 's/\(.*\.\)dat/\.txt/'`
          done
          

          从上面看,这段代码只是去掉了扩展:

          echo $i |sed 's/\.dat//'
          

          这部分将 .dat 更改为 .txt:

          echo $i | sed 's/\(.*\.\)dat/\.txt/'
          

          通过将它们相互碰撞,它将两个输出连接到文件名中。就像这样做:

          mv [filename][.dat] [filename] + [.txt]
          

          不过,我确实使用了 STDOUT 而不是“mv”命令。

          【讨论】:

          • 我在投票最多的答案中遇到了同样的问题,但是,投票最多的答案更简洁,并为我提供了足够的细节以使其发挥作用。
          【解决方案7】:

          以下命令将文件扩展名.c更改为.h

          find . -depth -name "*.c" -exec sh -c 'dname=$(dirname {}) && fname=$(basename {} .c) && mv {} $dname/$fname.h' ";"
          

          【讨论】:

            【解决方案8】:

            要重命名(更改扩展名)我在 epub 文件上的所有 html 文件,我使用以下命令行:

            find . -name "*.html*" -exec rename -v 's/\.html$/\.epub/i' {} \;
            

            【讨论】:

              【解决方案9】:

              Bash 可以完成所有繁重的工作,例如提取扩展名并标记新的扩展名。例如:

              for file in $1/*.dat ; do mv "$file" "${file%.*}.txt" ; done
              

              【讨论】:

              • 欢迎来到 Stack Overflow!虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
              • 这是一个 bash 解决方案,而 OP 要求提供一个 shell 解决方案。不适用于 POSIX 环境。
              猜你喜欢
              • 2010-10-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-27
              • 2016-06-29
              • 2016-05-27
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多