BASH - 根据文件类型重命名图片

时间:2013-12-23 19:08:25

标签: bash

我有点沮丧,试图让一个看似简单的bash脚本正常运行。我相信这是由于文件名很长或文件中的空格。

简而言之,我正在尝试从文件命令中提取数据,并将目录中的图片重命名为正确的文件类型,因为某些文件似乎被错误标记。例如,.png文件实际上是.jpg文件。这导致一些图像查看者不显示它们。这是我正在使用的脚本。

#!/bin/bash
for NAME in $(ls); do

if [ "$(file $NAME|grep GIF)" ]; then

echo "Renaming ${NAME} to ${NAME%.*}.gif"
mv ${NAME} ${NAME%.*}.gif

elif [ "$(file $NAME|grep JPG)" ]; then

echo "Renaming ${NAME} to ${NAME%.*}.jpg"
mv ${NAME} ${NAME%.*}.jpg

elif [ "$(file $NAME|grep PNG)" ]; then

echo "Renaming ${NAME} to ${NAME%.*}.png"
mv ${NAME} ${NAME%.*}.png

else

echo "No Change For ${NAME}"

fi
done

最后的回声只是为了看它失败的原因,这就是我所看到的:

No Change For 20097489744.jpeg
No Change For 24902583463

然后它就挂了,为什么?因为我相信该文件包含空格...我只是通过增加文件名来大量重命名目录中的所有文件,IE:1.jpg 2.png 3.gif然而我在网上找到的所有内容都是不要增加文件重命名作业,而是从名称和类似的东西中删除数字..所以,我已经碰壁,没有手动重命名130K文件(不会发生!哈哈)

我非常感谢那些来自brainiacs的任何意见!

谢谢,节日快乐!

4 个答案:

答案 0 :(得分:2)

这是一个完整的shell脚本解决方案,它处理包含空格和用例的文件名:

#!/bin/bash
ls | while read NAME ; do

  FILE_NAME="${NAME%.*}"
  FILE_EXT="${NAME##*.}"

  case $(file "$NAME") in
    *GIF*  ) NEW_EXT='gif' ;;
    *JPEG* ) NEW_EXT='jpg' ;;
    *PNG*  ) NEW_EXT='png' ;;
    *      ) NEW_EXT='' ;;
  esac

  if [[ -n "${NEW_EXT}" && "${FILE_EXT}" != "${NEW_EXT}" ]] ; then
    echo "Renaming ${NAME} to ${FILE_NAME}.${NEW_EXT}"
    mv "${NAME}" "${FILE_NAME}.${NEW_EXT}"
  else
    echo "No Change For ${NAME}"
  fi
done

我故意保持简单,但如果您有任何问题请与我联系

答案 1 :(得分:1)

你需要适当引用。如果您有${NAME},请将其更改为"${NAME}"(或等效"$NAME")。如果您只有$NAME,请将其更改为"$NAME"。等

另外,for NAME in $(ls)错了;你最有可能的意思是for NAME in *

最后,您可能希望将if [ "$(file $NAME|grep GIF)" ]; then替换为更简单且更具惯用性的if file "$NAME" | grep -q GIF; then ...(这最初建议在 - 现在已删除 - 由@phs回答。 )

答案 2 :(得分:1)

如果您的文件名包含空格,请使用:

mv "$NAME" "${NAME%.*}.png"

顺便说一下,

 [ "$(file $NAME|grep GIF)" ]; 

可以使用以下方法保存子进程:

 [[ $(file $NAME) == *GIF ]]; 

使用grep时,您可能应该使用grep 'GIF$',否则会在文件名中的任何位置找到GIF。

答案 3 :(得分:0)

如果您安装了ImageMagick,可以尝试识别命令。

  

例如,如果24902583463.png文件实际上是.jpg文件,则可以执行:

#command
identify 24902583463.png
# out
24902583463 JPEG 800x600 800x600+0+0 8-bit DirectClass 304KB 0.000u 0:00.000

#Now get the typeFile:
identify -format "%m" 24902583463.png
# Output
JPE

# Get only name (without extention)
identify -format "%t" 24902583463.png
24902583463

# Get corrent extension (without name)
identify -format "%e" 24902583463.png
png

所有在一个脚本中:

ls | while read NAME ; do
    identify -quiet "$NAME";
    if [ "$?" -eq "0" ]
    then
        FILE_NAME=$(identify -format "%t" "$NAME");
        FILE_EXT=$(identify -format "%e" "$NAME");
        FILE_TYPE=$(identify -format "%m" "$NAME" | tr '[:upper:]' '[:lower:]');
        if [ $FILE_EXT != $FILE_TYPE ];
            then
            mv  "$NAME" "${FILE_NAME}.${FILE_TYPE}";
        fi
    fi
done