简体   繁体   English

使用命令 Output(带空格)作为其他命令输入(BASH)

[英]Using command Output (with spaces) as other command Input (BASH)

Any one know why this works?有人知道为什么会这样吗?

cat `echo "FilenameWithoutSpaces.txt"` # shows file content

stdout:标准输出:

SHOW FILE CONTENT显示文件内容

And this not?这不是吗?

cat `echo "Filename\ With\ Spaces.txt"` # trying to show "Filename With Spaces.txt" content

stdout:标准输出:

cat: 'Filename': No such file or directory cat:'文件名':没有这样的文件或目录

cat: 'With': No such file or directory cat: 'With': 没有这样的文件或目录

cat: Spaces.txt: No such file or director cat: Spaces.txt: 没有这样的文件或目录

What would be the correct way to pass an output (with spaces) as a input of another command?将 output (带空格)作为另一个命令的输入传递的正确方法是什么?

The example above is a simplified case of what i need.上面的例子是我需要的一个简化案例。 What I have to to is:我必须做的是:

To use list of files (that may contain spaces) returned by a command as argument for another command.使用命令返回的文件列表(可能包含空格)作为另一个命令的参数。

For this particular case:对于这种特殊情况:

cat "$(echo "Filename\ With\ Spaces.txt")"

Since the case is a bit contrived, I can't really say what the correct thing is for your actual situation.由于案例有点做作,我不能真正说出适合您的实际情况的正确方法。 What is meant by a "list of files"? “文件列表”是什么意思? Is that a list of files that are separated by newlines?那是由换行符分隔的文件列表吗? How will you handle files that contain a newline in the name?您将如何处理名称中包含换行符的文件? Is it a list of null separated files, or is the list comma separated?是 null 分隔文件的列表,还是列表逗号分隔? In general, my opinion would be that the correct solution is to ban the use of whitespace in filenames.一般来说,我认为正确的解决方案是禁止在文件名中使用空格。 If that's not an option, the general principle would be to always put quotes around any string that may contain elements of IFS.如果这不是一个选项,一般原则是始终在可能包含 IFS 元素的任何字符串周围加上引号。

However.然而。 (Note this "however" should be read as "the following is a terrible hack that should never be done because the correct approach is to ban the use of whitespace in filenames"). (注意这个“然而”应该被理解为“以下是一个可怕的黑客,永远不应该这样做,因为正确的方法是禁止在文件名中使用空格”)。 Assuming that by a "list of files" you mean that each name is distinguished from the next by the presence of a newline in the string, you might try something like:假设通过“文件列表”,您的意思是每个名称都通过字符串中的换行符与下一个名称区分开来,您可以尝试以下操作:

printf '1st name\n2nd name\n' | { a=(); while read arg; do a+=("$arg"); done; 
    cmd "${a[@]}"
}

The above will invoke cmd with each line as a single argument.上面将调用cmd ,每行作为单个参数。 It would be much more reasonable to require that the list of inputs be zero separated, which would allow you to use xargs with something like:要求输入列表以零分隔会更合理,这将允许您将xargs与以下内容一起使用:

printf '1st name\0002nd name\000' | xargs -0 cmd

Until you properly define what you mean by "list of files", no robust solution is possible.除非您正确定义“文件列表”的含义,否则不可能有可靠的解决方案。

This is due to the way strings are handled and passed are argument in bash.这是由于处理和传递字符串的方式是 bash 中的参数。 When you run echo "Filename\ With\ Spaces.txt" the output is Filename With Spaces.txt which is exaclty what you are expecting.当您运行echo "Filename\ With\ Spaces.txt"时,output 是Filename With Spaces.txt ,这正是您所期望的。 So the full command is essentially the same as cat Filename With Spaces.txt and cat is trying to find 3 files with the names Filename, With, and Spaces.txt.所以完整的命令本质上与cat Filename With Spaces.txt相同,并且 cat 试图查找名称为 Filename、With 和 Spaces.txt 的 3 个文件。

When bash looks for those is it not likely to find them and spits out those error messages you are seeing.当 bash 查找这些时,它不太可能找到它们并吐出您看到的那些错误消息。 When there are no spaces, the filename is read as a single parameter and so you do not encounter the same issue.当没有空格时,文件名将作为单个参数读取,因此您不会遇到同样的问题。

To force the command to work with and without spaces you need to add qutoations around the command substituion:要强制命令使用和不使用空格,您需要在命令替换周围添加引号:

cat "`echo "Filename\ With\ Spaces.txt"`"

This command will expand the out put of the echo and keep it as a single argument.此命令将扩展echo的输出并将其保留为单个参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM