Bash和带空格的文件名 [英] Bash and filenames with spaces

查看:109
本文介绍了Bash和带空格的文件名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个简单的bash命令行:

The following is a simple Bash command line:

grep -li 'regex' "filename with spaces" "filename"

没有问题。另外,以下工作就好了:

No problems. Also the following works just fine:

grep -li 'regex' $(<listOfFiles.txt)

其中, listOfFiles.txt 包含文件名列表中grepped一
每行的文件名。

where listOfFiles.txt contains a list of filenames to be grepped, one filename per line.

listOfFiles.txt 包含文件名时出现问题
嵌入的空格。在我试过(见下文)所有的情况下,击分裂
在空格的文件名等等,例如, listOfFiles.txt A线
含有如 ./这个名字是file.xml 结束试图运行
每一块的grep( ./这个 A file.xml )。

The problem occurs when listOfFiles.txt contains filenames with embedded spaces. In all cases I've tried (see below), Bash splits the filenames at the spaces so, for example, a line in listOfFiles.txt containing a name like ./this is a file.xml ends up trying to run grep on each piece (./this, is, a and file.xml).

我想我是一个比较高级Bash用户,但我找不到
简单的魔法咒语,得到这个工作。下面是我以前做的事情
试过了。

I thought I was a relatively advanced Bash user, but I cannot find a simple magic incantation to get this to work. Here are the things I've tried.

grep -li 'regex' `cat listOfFiles.txt`

未能按上述(我真的不希望这个工作),所以我
想我把周围的每个文件名引号:

Fails as described above (I didn't really expect this to work), so I thought I'd put quotes around each filename:

grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt`

击跨$ P $点引号作为文件名的一部分,并给出了没有这样的
文件或目录的每个文件(还是的分裂与文件名
空格)

Bash interprets the quotes as part of the filename and gives "No such file or directory" for each file (and still splits the filenames with blanks)

for i in $(<listOfFiles.txt); do grep -li 'regex' "$i"; done

这未按原企图(即,它的行为就好像
报价是忽略不计),是非常缓慢的,因为它能够启动一个人的grep'
每个流程文件,而不是加工于一体的调用中的所有文件。

This fails as for the original attempt (that is, it behaves as if the quotes are ignored) and is very slow since it has to launch one 'grep' process per file instead of processing all files in one invocation.

下面的工作,但需要注意一些双逃逸,如果
常规的前pression包含shell元字符:

The following works, but requires some careful double-escaping if the regular expression contains shell metacharacters:

eval grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt`

这是构建命令行,以便它会的唯一途径
用空格正确处理文件名?

Is this the only way to construct the command line so it will correctly handle filenames with spaces?

推荐答案

试试这个:

(IFS=$'\n'; grep -li 'regex' $(<listOfFiles.txt))

IFS 是内部字段分隔符。将其设置为 $的'\\ n'告诉Bash使用换行符分隔的文件名。它的默认值是 $'\\ t \\ n',可以使用猫打印-etv&LT;&LT;&LT;$ IFS

IFS is the Internal Field Separator. Setting it to $'\n' tells Bash to use the newline character to delimit filenames. Its default value is $' \t\n' and can be printed using cat -etv <<<"$IFS".

括在括号中的脚本来启动子shell,这样只有括号由自定义受影响范围内的命令 IFS 值。

Enclosing the script in parenthesis starts a subshell so that only commands within the parenthesis are affected by the custom IFS value.

这篇关于Bash和带空格的文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆