贝 - 临时IFS因为只有换行符。为什么不这项工作:IFS = $(回声-e'\\ n') [英] shell - temp IFS as newline only. Why doesn't this work: IFS=$(echo -e '\n')

查看:699
本文介绍了贝 - 临时IFS因为只有换行符。为什么不这项工作:IFS = $(回声-e'\\ n')的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用的外壳文件名重复的进行空间。我在<读href=\"http://stackoverflow.com/questions/4128235/bash-shell-scripting-what-is-the-exact-meaning-of-ifs-n\">stackoverflow问题是的 IFS = $'\\ n'可用于这似乎很好地工作。然后我读<一个href=\"http://stackoverflow.com/questions/4128235/bash-shell-scripting-what-is-the-exact-meaning-of-ifs-n#comment9330981_4128305\">in到的答案之一的注释,使其POSIX比其他的bash兼容炮弹人们可以使用 IFS = $(回声-e'\\ n')

I'm trying to use for in the shell to iterate over filenames with spaces. I read in a stackoverflow question that IFS=$'\n' could be used and that seems to work fine. I then read in a comment to one of the answers that to make it posix compatible for shells other than bash one could use IFS=$(echo -e '\n').

前者的作品,但后者没有。注释是upvoted几次。我检查了输出和变量似乎并没有包含换行符。

The former works but the latter doesn't. The comment is upvoted several times. I checked the output and the variable doesn't seem to contain the newline.

#!/bin/sh

IFS=$(echo -e '\n')
echo -n "$IFS" | od -t x1
for file in `printf 'one\ntwo two\nthree'`; do
    echo "Found $file"
done

echo

IFS=$'\n'
echo -n "$IFS" | od -t x1
for file in `printf 'one\ntwo two\nthree'`; do
    echo "Found $file"
done

结果
输出显示字段分隔符缺少第一:


The output shows the field separator is missing for the first:

0000000
Found one
two two
three

结果
但是,在第二适当的:


But is proper on the second:

0000000 0a
0000001
Found one
Found two two
Found three

结果

我发现了一个问题,回答可能会或可能不会是我的问题的重复:结果
<一href=\"http://stackoverflow.com/questions/16831429/when-setting-ifs-to-split-on-newlines-why-is-it-necessary-to-include-a-backspac\">linux - 当设置IFS拆就换行,为什么有必要包括退格? - 堆栈溢出

I found an answered question which may or may not be a duplicate of my question:
linux - When setting IFS to split on newlines, why is it necessary to include a backspace? - Stack Overflow

有没有做什么有讨论,任何危险 IFS = $(回声克斯的'\\ n \\ B')?由于增加了一个 \\ b 来IFS(我检查)。可以在 \\ b 发生在文件名?我不希望我的code错误分割的文件名。

Is there any danger to doing what's discussed there, IFS=$(echo -en '\n\b')? Because that adds a \b to IFS (I checked). Can a \b occur in a file name? I don't want my code to split a file name by mistake.

另外你对如何妥善处理后, IFS恢复为循环任何建议?我是否应该将其存储在一个临时变量,或运行IFS和for语句在子shell? (以及如何做到这一点?)谢谢

Also do you have any recommendations on how to properly handle restoration of IFS after the for loop? Should I store it in a temporary variable, or run IFS and the for statement in a subshell? (and how to do that?) Thanks

推荐答案

更新 - 改变了我的伪注释一个真正的答案

Update - changing my pseudo-comment to a real answer.

我觉得<一个href=\"http://unix.stackexchange.com/questions/17732/where-has-the-trailing-newline-char-gone-from-my-command-substitution\">this回答应该解释你所看到的行为。具体命令替换操作符 $()和反引号将剥去命令输出尾随换行。然而,在第二个例子中,直接分配没有做任何命令subsitution,所以按预期工作。

I think this answer should explain the behavior you are seeing. Specifically command substitution operators $() and backticks will strip trailing newlines from the command output. However the direct assignment in your second example doesn't do any command subsitution, so works as expected.

所以我不敢说我​​觉得upvoted评论你指的是不正确。

So I'm afraid to say I think the upvoted comment you refer to is incorrect.

我想恢复IFS最安全的方法是将其设置在一个子shell。所有你需要做的就是把相关的命令在括号()

I think the safest way to restore IFS is to set it in a subshell. All you need to do is put the relevant commands in parentheses ():

(
    IFS=$'\n'
    echo -n "$IFS" | od -t x1
    for file in `printf 'one\ntwo two\nthree'`; do
        echo "Found $file"
    done
)

当然,调用一个子shell中会带来短暂的延迟,所以需要考虑性能,如果这是要重复多次。

Of course invoking a subshell incurs a small delay, so performance needs to be considered if this is to be repeated many times.

顺便说一句,要非常小心,文件名可以包含\\ b和\\ n。我认为,只是他们不能包含的字符只有斜线和\\ 0。至少那是什么它说这个维基百科文章

As an aside, be very careful, filenames can contain both \b and \n. I think just about the only characters they cannot contain are slash and \0. At least thats what it says on this wikipedia article.

$ touch $'12345\b67890'
$ touch "new
> line"
$ ls --show-control-chars
123467890  new
line
$ 

这篇关于贝 - 临时IFS因为只有换行符。为什么不这项工作:IFS = $(回声-e'\\ n')的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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