脚本中有以下代码片段:
bitrate=$(ffmpeg -i "$vidfile" 2>&1 | grep bitrate | \
perl -pe 's/.*bitrate: (\d{1,} .*)\r?\n\r?$/$1/')
echo "\$bitrate = $bitrate" #added for debugging
printf "\$bitrate = $bitrate\n" #added for debugging
printf " $bitrate $vidfile\n" #added for debugging
printf " %s %s \n\n" "$bitrate" "$vidfile"这个BASH脚本(减去为调试添加的行)工作得很好,就像在Mac终端上一样。当我试图在Cygwin上运行它时,最后一个和第二个printf不打印$bitrate变量的值。
运行的示例输出:
$ bitrate.sh 20180305-01.mov 20180305-02.mov
$bitrate = 31103 kb/s
$bitrate = 31103 kb/s
20180305-01.mov
20180305-01.mov
$bitrate = 30735 kb/s
$bitrate = 30735 kb/s
20180305-02.mov
20180305-02.mov发布于 2018-03-12 05:58:59
问题是由于不打印回车字符(有时表示为\r、^M或<CR>)。DOS和Windows使用这样的约定:文本行以回车结束,然后是行提要,但unix只使用linefeed。因此,当您使用DOS/Windows格式的行并将其交给unix程序(例如shell)时,它会认为linefeed是行的末尾,并将回车作为行内容的一部分。在Windows中使用unix工具(例如Cygwin)时,这个问题经常发生。
在这种情况下,我认为是因为脚本文件本身是DOS/Windows格式,但显然不是;所以我不确定回车是从哪里来的(也许perl试图与Windows兼容并输出DOS/Windows格式?)无论如何,最终的结果是变量bitrate有一个回车返回。打印它本身,这是不可见的,但如果您打印它后面的空格和文件名,它将"31103 kb/s\r 20180305-01.mov“发送到终端,该终端打印"31103 kb/s",然后回车返回使它回到行的开头(这实际上是”回车“的意思),然后在"31103 kb/s”的顶部打印“20180305-01.mov”,替换它。
解决方案:通过将tr -d '\r'添加到计算比特率的管道末尾,删除回车。
当您怀疑存在这样的问题时,使用printf的%q格式打印变量时,可以使用一些有用的疑难解答技巧:
$ printf 'the var is %q\n' "$bitratenormal"
the var is 31103\ kb/s
$ printf 'the var is %q\n' "$bitratewithcr"
the var is $'31103 kb/s\r'...and通过LC_ALL=C cat -vet运行文件以使各种通常不可见的字符可见:
$ cat filewithweirdchars
This line is normal
This line ends with a space
This line ends with a tab
This line ends with a carriage return
This line has nonbreaking spaces and “weird” unicode quotes
$ LC_ALL=C cat -vet filewithweirdchars
This line is normal$
This line ends with a space $
This line ends with a tab^I$
This line ends with a carriage return^M$
ThisM-BM- lineM-BM- hasM-BM- nonbreakingM-BM- spaces and M-bM-^@M-^\weirdM-bM-^@M-^] unicode quotes$https://stackoverflow.com/questions/49217188
复制相似问题