为什么行终止符会更改此 Bash 脚本的输出?

为什么行终止符会更改此 Bash 脚本的输出?

在调试脚本时,我终于找到了原因,但我不明白为什么。

一个制表符分隔的文本文件示例包含:

$ cat list1.txt
123 Fake St Miami   FL
456 None Rd San Francisco CA
789 Nowhere Dr  Denver  CO

最初使用 vi 创建,文件将其标识为

$ file list1.txt
list1.txt: ASCII text

运行这一行(编辑:将帖子更改为多行以提高可读性)将每一行读入 3 个变量,打印顺序如脚本中指定。请注意,字符串的连接非常复杂,因为我在调试时试图非常明确地说明顺序:

$ while IFS="     " read -r addr1 city state
do
  data0="'"
  data1='companyName=&'
  data2="address1=$addr1"
  data3='&city='
  data4="$city"
  data5='&state='
  data6="$state"
  data7='&urbanCode=&zip='
  data8="'"
  data=${data0}${data1}${data2}${data3}${data4}${data5}${data6}${data7}${data8}
  echo "$data"
done < list1.txt

'companyName=&address1=123&city=Fake&state=St   Miami   FL&urbanCode=&zip='
'companyName=&address1=456&city=None&state=Rd   San Francisco CA&urbanCode=&zip='
'companyName=&address1=789&city=Nowhere&state=Dr    Denver  CO&urbanCode=&zip='

更改文件 list1.txt DOS 格式会导致输出重新排序

$ unix2dos list1.txt
unix2dos: converting file list1.txt to DOS format...
$ file list1.txt
list1.txt: ASCII text, with CRLF line terminators
$ while IFS="     " read -r addr1 city state; do  data0="'";  data1='companyName=&';  data2="address1=$addr1";  data3='&city=';  data4="$city";  data5='&state=';  data6="$state";  data7='&urbanCode=&zip=';  data8="'";  data=${data0}${data1}${data2}${data3}${data4}${data5}${data6}${data7}${data8};  echo "$data"; done < list1.txt
&urbanCode=&zip='ress1=123&city=Fake&state=St   Miami   FL
&urbanCode=&zip='ress1=456&city=None&state=Rd   San Francisco CA
&urbanCode=&zip='ress1=789&city=Nowhere&state=Dr    Denver  CO

为什么会发生这种情况? GNU bash,版本 3.2.57

答案1

当从 DOS 格式的文本文件中读取一行到三个变量中时,最后一个变量state将以回车符结尾。这是因为 DOS 文本文件使用字符序列 CR+LF(回车后换行)表示“换行”。 Unix 文本文件仅使用换行符换行,DOS 文本文件的回车符被视为行尾的任何其他字符。

当输出$state到终端时,这个回车符会导致输出的位置跳转到行首(这是回车符的用途,将“回车”(曾经是行式打印机的回车)返回到行首)并且以下字符串被放置在行的最开始,覆盖终端中这些位置先前输出的任何文本。

所以你会得到第一行,

'companyName=&address1=123&city=Fake&state=

$state后跟,的值St Miami FL,然后光标返回到行的开头,其中

&urbanCode=&zip='

输出,覆盖该行的第一部分,导致看起来很奇怪

&urbanCode=&zip='ress1=123&city=Fake&state=St   Miami   FL

相关内容