Bash 在文件名中使用空格读取时

Bash 在文件名中使用空格读取时,bash,while-loop,ffmpeg,Bash,While Loop,Ffmpeg,在这个.ogg文件上 $ tree . ├── Disc 1 - 01 - Procrastination.ogg ├── Disc 1 - 02 - À carreaux !.ogg ├── Disc 1 - 03 - Météo marine.ogg └── mp3 我尝试使用而循环将它们转换为mp3,并在文件名中保留空格:: $ ls *.ogg | while read line; do ffmpeg -i "$line" mp3/"$line".mp3 ; done 但我得到了这个

在这个
.ogg
文件上

$ tree
.
├── Disc 1 - 01 - Procrastination.ogg
├── Disc 1 - 02 - À carreaux !.ogg
├── Disc 1 - 03 - Météo marine.ogg
└── mp3
我尝试使用
循环将它们转换为mp3,并在文件名中保留空格::

$ ls *.ogg | while read line; do ffmpeg -i "$line" mp3/"$line".mp3 ; done
但我得到了这个错误::

$ ls *.ogg | while read line; do ffmpeg -i "$line" mp3/"$line".mp3 ; done
...
Parse error, at least 3 arguments were expected, only 0 given
in string ' 1 - 02 - À carreaux !.ogg' ...
...
这个报告即使看起来很相似,但它是针对一个更复杂的脚本,并且没有答案


这仅在输出为http://URL时解决,使用
find-print0
获取NUL分隔的文件列表,而不是解析
ls
输出,这从来都不是一个好主意:

#!/bin/bash

while read -d '' -r file; do
  ffmpeg -i "$file" mp3/"$file".mp3 </dev/null
done < <(find . -type f -name '*.ogg' -print0)

见:


使用
find-print0
获取NUL分隔的文件列表,而不是解析
ls
输出,这从来都不是一个好主意:

#!/bin/bash

while read -d '' -r file; do
  ffmpeg -i "$file" mp3/"$file".mp3 </dev/null
done < <(find . -type f -name '*.ogg' -print0)

见:


    • 这里不需要循环;让
      find
      为您执行命令

      find . -type f -name '*.ogg' -exec ffmpeg -i {} mp3/{}.mp3 \;
      
      或者,如果要从结果中删除
      .ogg
      扩展名:

      find . -type f -name '*.ogg' -exec sh -c 'ffmpeg -i "$1" mp3/"${1%.ogg}.mp3"' _ {} \;
      
      相反,您可以跳过
      查找

      shopt -s extglob
      for f in **/*.ogg; do
        [[ -f $f ]] || continue
        ffmpeg -i  "$f" mp3/"${f%.ogg}.mp3"
      done
      

      这里不需要循环;让
      find
      为您执行命令

      find . -type f -name '*.ogg' -exec ffmpeg -i {} mp3/{}.mp3 \;
      
      或者,如果要从结果中删除
      .ogg
      扩展名:

      find . -type f -name '*.ogg' -exec sh -c 'ffmpeg -i "$1" mp3/"${1%.ogg}.mp3"' _ {} \;
      
      相反,您可以跳过
      查找

      shopt -s extglob
      for f in **/*.ogg; do
        [[ -f $f ]] || continue
        ffmpeg -i  "$f" mp3/"${f%.ogg}.mp3"
      done
      

      与shopt的for循环。。。工作很好;但这段时间不起作用。ffmpeg挂起在第一个文件的末尾:“…输出#0,mp3,到'mp3//光盘1-02-Àcarreaux!.ogg.mp3':大小=378kB时间=00:00:24.16比特率=128.2kbit/s速度=48.3x回车命令:| all |-1[]”@user3313834,放置
      带有shopt的for循环。。。工作很好;但这段时间不起作用。ffmpeg挂起在第一个文件的末尾:“…输出0,mp3,到'mp3//光盘1-02-carreaux!.ogg.mp3':大小=378kB时间=00:00:24.16比特率=128.2kbit/s速度=48.3x输入命令:| all |-1[]”@user3313834,输入
      作为您的第一个答案,我猜
      \在第二次工作时丢失,但我不明白末尾的
      {}
      是什么当您运行
      sh-c'.'
      时,下一个参数在新shell中设置
      $0
      的值。你很少关心这个价值是什么;我使用
      \uu
      作为虚拟值
      {}
      是通过
      find
      传递的当前文件,shell以
      $1
      的形式访问该文件在第二次工作时丢失,但我不明白末尾的
      {}
      是什么当您运行
      sh-c'.'
      时,下一个参数在新shell中设置
      $0
      的值。你很少关心这个价值是什么;我使用
      \uu
      作为虚拟值
      {}
      是通过
      find
      传递的当前文件,shell以
      $1
      的形式访问该文件。