行終端がこの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バッシュ、バージョン3.2.57

ベストアンサー1

DOS形式のテキストファイルから3つの変数で1行を読み取ると、最後の変数は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

おすすめ記事