Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash:空格和元字符(如*)有问题。似乎不可能_Bash_Shell_Wildcard_Spaces - Fatal编程技术网

Bash:空格和元字符(如*)有问题。似乎不可能

Bash:空格和元字符(如*)有问题。似乎不可能,bash,shell,wildcard,spaces,Bash,Shell,Wildcard,Spaces,这是我的问题:我有一个名称列表,每行1个,可以匹配或不匹配系统上的一些文件。 我想使用元字符来匹配系统上的文件 如果我有两个名字的列表:“abc”和“re*”,并且在我的系统3文件中:reinc recsa reini 我想写一些代码来处理两个参数“abc”和“re*”,并获得文件列表每行一个。 我尝试的是错误的,结果我成功了 a b c reinc recsa reini 或 但这似乎不可能实现 a b c reinc recsa reini 你有什么想法吗 我尝试的例子如下: $ ls

这是我的问题:我有一个名称列表,每行1个,可以匹配或不匹配系统上的一些文件。 我想使用元字符来匹配系统上的文件

如果我有两个名字的列表:“abc”和“re*”,并且在我的系统3文件中:reinc recsa reini

我想写一些代码来处理两个参数“abc”和“re*”,并获得文件列表每行一个。 我尝试的是错误的,结果我成功了

a
b
c
reinc
recsa
reini

但这似乎不可能实现

a b c
reinc
recsa
reini
你有什么想法吗

我尝试的例子如下:

$ ls
list  recsa  reinc  reini
$ cat list
a b c
re*
$ cat list | while read name; do echo $name; done
a b c
recsa reinc reini
$ cat list | while read name; do for file in $name; do echo "$file"; done; done
a
b
c
recsa
reinc
reini
$

如果我理解正确,您希望对每个参数应用通配符扩展(),但不是。Bash无法做到两者兼而有之:双引号(或其他类似双引号的上下文)之外的变量替换或命令替换同时执行这两种操作,并且没有任何构造可以只执行一种操作。但两者都可以配置为无操作

要有效禁用分词,请设置为空字符串

IFS=
while read -r line; do
  printf '%s\n' $line
done <list
unset IFS
如果您想要相反的结果(在不扩展文件名的情况下进行分词),可以使用
set-f
禁用文件名扩展。或者你可以使用
read
,它也可以进行分词,但你必须事先知道有多少个单词


除了使用
local
,我的答案适用于所有非仿古sh变体,而不仅仅是bash。Zsh有更好的方法,但标准方法也适用于(k)sh仿真模式。

使用
compgen-G
扩展通配符/全局符,如
*
compgen
的输出是每行一个匹配项。如果没有匹配项(例如
compgen-G不存在\u文件
),则没有输出。如果我没弄错,那么在这种情况下,您需要打印
不存在的\u文件。您可以通过检查
compgen
的存在状态来执行此操作

while IFS= read -r pattern; do
  compgen -G "$pattern" || printf %s\\n "$pattern"
done < list
而IFS=read-r模式;做
compgen-G“$pattern”| | printf%s\\n“$pattern”
完成<列表

很难理解您的输入和输出。你的系统上有六个文件,我猜是“abc reinc recsa reni”。如果他们被命名为别的什么呢?你想完成什么一般任务?你能澄清一下吗?是否要编写bash脚本?什么是“两个名字”?这就是脚本的参数吗?这两个参数与文件的关系如何?如果两个参数中的任何一个是文件名的前缀,或者只是第二个参数,那么是否应该打印文件名?你对前缀感兴趣,还是有不同的逻辑?你好,我在post上添加了一个示例,所以你有两行,每一行都是参数列表。您希望第一行被逐字回复,第二行被shell扩展,每个结果都在一个新行上。文件中是否有超过两行的内容?第二行是否会包含多个图案?第一行是否包含元字符,或仅包含文字字符串?该任务需要很长时间才能描述,因此我将问题简化为对我来说有问题的内容。为了简化,我这样做是因为我将通过ssh将结果传递给tar命令的STDIN。我想扩展元字符,比如?*[],并用空格处理名称。文件可能存在或不存在于系统上,如果没有文件,因此使用re*是一个好主意设置
IFS=
。您可以使用
IFS=$'\n'在没有循环的情况下进行处理;printf%s\\n$(
。它需要多一点内存,但这不应该是个问题。Bash内置的
printf
ARG\u MAX
来说都是毫无疑问的。谢谢!我试试看。我不知道IFS也会影响分词。你用几句好话很好地描述了我的问题!事实上,我使用内置命令echo和stdin/stdout来处理arg_max限制,所以这个带有printf的解决方案看起来非常好。我不认为我可以关闭bash函数,我认为我还有很多东西要学习,我应该阅读整个手册以提高效率谢谢。有趣!我也会详细尝试一下
act_on_list () {
  local IFS=
  while read -r line; do
    printf '%s\n' $line
  done <list
}
act_on_list
while IFS= read -r pattern; do
  compgen -G "$pattern" || printf %s\\n "$pattern"
done < list