【问题标题】:pipe output of "file" to "mv" to rename files with file-extension“file”的管道输出到“mv”以使用文件扩展名重命名文件
【发布时间】:2016-05-16 16:06:00
【问题描述】:

以下情况: 一个包含许多不同图像文件的文件夹:jpeg、png、gif 文件 * 的输出类似于:

filename1: png image data, 300 x 300, some more information bla bla
filename2: gif image data, 300 x 300, some more information bla bla
filename3: jpeg image data, 300 x 300, some more information bla bla

现在,最好的方法是在文件中附加一个后缀(如 image.png),因为这些文件的名称类似于“avatar_pobmglinmphfhbiffgmdmphklcbjolklmnaeblbk”。 所以问题是命令“file”没有选项(afaik)只输出文件类型和文件名/-path

我的想象是管道或 find -exec 里面有文件。

非常感谢您的帮助!

【问题讨论】:

标签: bash


【解决方案1】:

使用readprocess substitution

while IFS=' ' read img ext n; do
  mv ${img%:} ${img%:}.${ext}
done < <(file *)

${img%:} 语法是shell parameter expansion 的一部分。它会从图像名称中去除尾随的 :

进程替换&lt;(file *) 允许将命令输出作为文件处理。 file * 输出在此处重定向为 read 命令的输入。

【讨论】:

  • 除了大括号内冒号前面的 % 和完成后的 mv: rename icon_1158036545: PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced to icon_1158036545: PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced.: No such file or directory 有什么不正确的?
  • 我已经添加了一些解释并更新了脚本(将IFS 设置为空格)。
  • 它有效!非常感谢!是 n 变量(我认为它是一个?)来捕捉在这种用法中是垃圾的其余行还是有更多的事情要做?此外,我将阅读read 的人,以更好地了解此循环中的所有内容。非常感谢您的帮助!
  • 不客气! n 变量是对的,它只是在这里用来捕捉其余的行,没有别的。
【解决方案2】:

你可以使用mv + cut

IFS=$'\n'
for line in $(file *); do 
  filename=$(echo $line | cut -d: -f1)
  extension=$(echo $line | cut -d' ' -f2)
  mv $filename "${filename}.${extension}"
done

【讨论】:

  • 这是一个脚本解决方案,不是吗?我可以直接在 bash shell 中以单行方式写这个吗?类似于: for line in $(file *); do filename=$(echo $line | cut -f1 | tr -d ':') && extension=$(echo $line | cut -f2) && mv $filename "${filename}.${extension}";完毕;那是正确的吗?谢谢
  • 1) 您可以在 bash shell 中编写此代码,而无需将其制成 1-liner ; 2) 更好的 1-liner 将是 for line in $(file *); do mv $(echo $line | cut -f1 | tr -d ':') "$(echo $line | cut -f1 | tr -d ':').$(echo $line | cut -f2)"; done 但是是的,你的看起来是正确的
  • 它不起作用...mv: rename PNG to PNG.PNG: No such file or directory mv: rename image to image.image: No such file or directory mv: rename data, to data,.data,: No such file or directory mv: rename 300 to 300.300: No such file or directory mv: rename x to x.x: No such file or directory 似乎在 cut -f1/-f2 部分中有一些不正确...
  • 好的,有两个问题:for 循环使用单词而不是行,cut 绕过制表符而不是空格;我已经更新了我的答案以说明两者
  • 非常感谢,它有效!我尝试在第一个剪切命令中将 tr 命令替换为冒号作为分隔符,例如:IFS=$'\n' &amp;&amp; for line in $(file *); do filename=$(echo $line | cut -d: -f1) &amp;&amp; extension=$(echo $line | cut -d' ' -f2) &amp;&amp; mv $filename "${filename}.${extension}"; done 你是否使用 tr 命令允许文件名中使用冒号?另一个问题是,为什么我需要 mv 后半部分的大括号? mv $filename "${filename}.${extension}"?这是取变量而不是bash的$文件名吗? (是 bash 中的 $filename 吗?)非常感谢!
猜你喜欢
  • 2016-12-06
  • 1970-01-01
  • 2014-04-10
  • 2021-01-14
  • 1970-01-01
  • 2011-08-06
  • 2013-05-17
  • 2017-04-23
  • 1970-01-01
相关资源
最近更新 更多