所以,问题是-我有一个文件列表,我想把它们发送到一个程序中,这样它就可以在相同的进程中处理这个列表。我的意思是,例如,我有一堆视频文件,我想玩mpv,但我需要把它们传递到一个特定的顺序,我可以用ls video\ * | sort -k2创建。每个文件的名称都类似于video [number] - [title].mp4。我想按[number]列对它们进行排序,所以我调用了ls和sort程序,因为我的shell (zsh)不能通过它自己来完成这种事情(我认为)。
所以我输入了ls video\ * | sort -k2,它给了我一个我想要的排序列表。但是,当我试图用mpv $(ls video\ * | sort -k2)将其传递到mpv时,出于某种原因,mpv不逐行读取文件名,而是从一个空间读取到另一个空间(我的意思是,这不是mpv的问题,而是shell给了mpv以空格而不是行分隔的参数)。
我试着用引号包装每一行,尝试创建一个单线列表,同时尝试两者,但如果成功的话,则没有。Shell总是按空格分隔文件名空间,它忽略换行符或引号。都是因为空间,不是吗?
发布于 2020-06-09 10:04:14
为什么“mpv $(ls视频\*)”与“mpv视频\*”不同?
因为https://www.gnu.org/software/bash/manual/bash.html#Command-Substitution的结果经历了https://www.gnu.org/software/bash/manual/bash.html#Word-Splitting,而https://www.gnu.org/software/bash/manual/bash.html#Filename-Expansion的结果却没有,因为单词分裂发生在文件名展开之前(参见壳展开)。
分词是一种神奇的东西,当参数不被引用时,它就会使用空格为参数喷出。这意味着,对于一个只打印具有var="a b c variable with spaces"; f $var的参数计数的函数--当$var未量化时,f函数将接收6个参数-- $var展开的结果将在空白空间中被喷出。
当命令替换的结果不被引用时,就会发生分词现象。这意味着在f $(echo a b c)中,函数f将接收3个参数。
因为您的文件中有一个空格,所以video\ * --当您传递命令ls输出带有空格的字符串的未引号的结果时,它将在空白空间上显示出来。因此,video和其他部分将是单独的参数。
不要解析ls。ls是用来在外壳中打印的--没有别的。大多数情况下都很容易转换为find -exec或find | xargs,例如,您想要:find . -maxdepth 1 -type f -name 'video *' | sort -k2 | xargs -d '\n' mpv,甚至更好地使用零终止流:find . -maxdepth 1 -type f -name 'video *' -print0 | sort -z -k2 | xargs -0 mpv。
都是因为空间,不是吗?
是。
https://stackoverflow.com/questions/62279693
复制相似问题