奇怪的“回声" Shell脚本中的行为 [英] Strange "echo" behavior in shell script
问题描述
我想以这种方式打印从数组拆分中获得的内容:
I want to print the content that I have obtained from the split of an array in this way:
string="abc test;ABCtest.it"
IFS=';' read -a array <<< "$string"
name="${array[0]}"
url="${array[1]}"
echo -ne "\n$url,$name" >> "$outputDir/$fileName"
但是输出文件不包含URL部分.
But the output file doesn't contain the URL part.
我认为问题出在.
,但我不知道如何解决.
I think that the problem is the .
, but I don't know how to fix it.
如果我尝试这个
echo $url
有效!
我也尝试过使用printf
和硬编码的文件名,但是什么也没有!
I've tried also with printf
and with an hardcoded filename, but nothing!
printf '%s %s\n' "$url" "$name" >> test.txt
当我尝试在变量$url
之后连接另一件事时,该变量的某些部分被删除或覆盖到输出文件中.
It seems that when I try to concatenate another thing after the variable $url
, some part of the variable is deleted or overwritten into the output file.
例如,如果我尝试这样做:
For example, if I try with this:
printf '%s %s\n' "$url" "pp" >> test.txt
我用一个简单的cat test.txt
得到的是:
What I get with a simple cat test.txt
is this:
pptest.it
,但变量$url
的内容必须为ABCTest.it
.
but the content of the variable $url
must be ABCTest.it
.
推荐答案
以补充 chepner的有用答案:
-
如果输出没有看起来您期望的样子,则始终值得检查其内容寻找隐藏的控制字符 ,这些字符可能会更改数据在输出中的外观 .
If output doesn't look what you expect it to look like, it's always worth examining its contents to look for hidden control characters that may change data's appearance on output.
\r
,CR(回车; ASCII值13)是一个臭名昭著的示例,其原因有二:
\r
, a CR (carriage return; ASCII value 13) is a notorious example for two reasons:
- (如@chepner所述),它将光标移动到行中间字符串的开头,从而有效擦除了至少一部分行前字符;例如.:
-
echo $'abcd\refg'
打印efgd
:\r
导致所有内容在行的开头重新开始打印,而字符串 before 中的d
仍然存在,\r
,因为它恰好是 1个字符.长于 之后的字符串.
(注意:$'...'
语法是所谓的 ANSI C引号的字符串,它允许使用转义序列(例如,$'...\r...'
中的\r
)来创建实际控制字符.)
- (As @chepner has stated) it moves the cursor to the beginning of the line mid-string, effectively erasing at least part of what came before it; e.g.:
echo $'abcd\refg'
printsefgd
: the\r
causes everything after to restart printing at the beginning of the line, with only thed
from the string before the\r
surviving, because it happened to be 1 char. longer than the string that came after.
(Note: The$'...'
syntax is a so-called ANSI C-quoted string, which allows use of escape sequences such as\r
in$'...\r...'
to create actual control characters.)
-
^M
代表\r
(CR) -
^I
代表\t
(制表符) -
^[
代表ESC字符. -
... # see 'man cat'
- 行尾表示为
$
- 因此,具有Windows样式的行尾的文件将在
cat -et
输出的行末显示^M$
.
^M
represents a\r
(CR)^I
represents a\t
(tab. char)^[
represents an ESC char.... # see 'man cat'
- The end of a line is represented as
$
- Thus, a file with Windows-style line endings will show
^M$
at the end of the lines output bycat -et
.
-
echo $'abcd\refg' | cat -et # -> 'abcd^Mefg$' - note the ^M
-
awk 'sub("\r$", "")+1' win.txt > unix.txt
- 请注意,此POSIX兼容命令不允许您就地替换文件 ,但是:
- 如果您具有 GNU
sed
,则以下代码将执行转换:-
sed -i 's/\r$//' winIn_UnixOut.txt
awk 'sub("\r$", "")+1' win.txt > unix.txt
- Note that this POSIX-compliant command doesn't allow you to replace the file in-place, however:
- If you have GNU
sed
, the following would perform the conversion in place:sed -i 's/\r$//' winIn_UnixOut.txt
-
sed -i '' $'s/\r$//' winIn_UnixOut.txt
这篇关于奇怪的“回声" Shell脚本中的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- If you have GNU
-
- 如果您具有 GNU
-