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
Shell zsh:从文件中读取的带制表符的字符串不等于iteslf_Shell_Zsh - Fatal编程技术网

Shell zsh:从文件中读取的带制表符的字符串不等于iteslf

Shell zsh:从文件中读取的带制表符的字符串不等于iteslf,shell,zsh,Shell,Zsh,这完全把我难住了。 基本上,当我将字符串写入文件,然后将其读回时,字符串本身并不相等。 如何测试从文件中读取的字符串是否等于预期值 例如: ➜ foo="foo\tbar" ➜ echo $foo > foo.txt ➜ bar=`head -n 1 foo.txt` ➜ printf $foo | od -x 0000000 6261 6463 6509 6766 0000010 ➜ printf $bar | od -x 0000000 6261 6463 6509 6766 00

这完全把我难住了。
基本上,当我将字符串写入文件,然后将其读回时,字符串本身并不相等。
如何测试从文件中读取的字符串是否等于预期值

例如:

➜ foo="foo\tbar"
➜ echo $foo > foo.txt
➜ bar=`head -n 1 foo.txt`

➜ printf $foo | od -x
0000000 6261 6463 6509 6766
0000010

➜ printf $bar | od -x
0000000 6261 6463 6509 6766
0000010

➜ [ $bar != $foo ] && echo "they are not equal ????"
they are not equal ????
在我看来,这两个变量显然是相等的。为什么bash认为它们不相等

如果我在字符串中没有
\t
的情况下运行上述测试,那么等式工作正常,因此我认为制表符与此有关

但是,如果我在包含制表符的情况下直接将
$bar
设置为
$foo
$bar=$foo
),则等式通过,因此不能直接由字符串中存在制表符引起

这是怎么回事?如何确保文件的第一行与带制表符的字符串匹配


所有测试都使用zsh运行。

zsh
echo
实现符合POSIX标准,因此在将值写入
foo.txt
时,
foo
值中的文字字符
\
t
转换为文字ASCII制表符
printf
还处理
\t
。使用
declare-p
,您可以看到
foo
bar
确实是不同的:

% declare -p foo bar
typeset foo='foo\tbar'
typeset bar=$'foo\tbar'
或正确使用
printf

192% printf '%s' $foo | od -x
0000000      6f66    5c6f    6274    7261
0000010
192% printf '%s' $bar | od -x
0000000      6f66    096f    6162    0072
0000007
您还可以看到长度不同:

% echo ${#foo} ${#bar}
8 7
但是,您可能首先需要一个值为
foo
的文本选项卡:

% foo=$'foo\tbar'
% printf '%s' $foo | od -x
0000000      6f66    096f    6162    0072
0000007

zsh
echo
的实现符合POSIX标准,因此在将值写入
foo.txt
时,
foo
值中的文字字符
\
t
将转换为文字ASCII制表符
printf
还处理
\t
。使用
declare-p
,您可以看到
foo
bar
确实是不同的:

% declare -p foo bar
typeset foo='foo\tbar'
typeset bar=$'foo\tbar'
或正确使用
printf

192% printf '%s' $foo | od -x
0000000      6f66    5c6f    6274    7261
0000010
192% printf '%s' $bar | od -x
0000000      6f66    096f    6162    0072
0000007
您还可以看到长度不同:

% echo ${#foo} ${#bar}
8 7
但是,您可能首先需要一个值为
foo
的文本选项卡:

% foo=$'foo\tbar'
% printf '%s' $foo | od -x
0000000      6f66    096f    6162    0072
0000007

非报价问题的可能副本
zsh
不会对参数扩展执行分词。如果您不使用bash测试答案,请不要标记bash。它们不是相互兼容的外壳。可能重复的不是引用问题
zsh
不会对参数扩展执行分词。如果您不使用bash测试答案,请不要标记bash。它们不是相互兼容的外壳。啊,我明白了。所以foo实际上存储为“foo\tbar”(不带制表符)。目前,我的解决方案是设置一个“expected\u foo”变量,如expected\u foo=`echo$foo`,然后在我的[…]语句中使用它。有没有更简洁的方法可以做到这一点?是的,只需使用答案末尾所示的
$'…'
引号。另外,请注意
bash
中的
echo“$foo”
可能会分别输出反斜杠和
t
,而不会用文字选项卡替换。有一些方法可以使bash
echo
POSIX兼容,但是默认情况下它们都是关闭的。要获得可预测的结果,请始终使用
printf
。啊,我明白了。所以foo实际上存储为“foo\tbar”(不带制表符)。目前,我的解决方案是设置一个“expected\u foo”变量,如expected\u foo=`echo$foo`,然后在我的[…]语句中使用它。有没有更简洁的方法可以做到这一点?是的,只需使用答案末尾所示的
$'…'
引号。另外,请注意
bash
中的
echo“$foo”
可能会分别输出反斜杠和
t
,而不会用文字选项卡替换。有一些方法可以使bash
echo
POSIX兼容,但是默认情况下它们都是关闭的。要获得可预测的结果,请始终使用
printf