シェルスクリプトでは、行末にテキストを追加することはできません。

シェルスクリプトでは、行末にテキストを追加することはできません。

ファイルから行を読み、文字列を追加したいと思います。ところがちゃんと付いていませんね。

#! /bin/bash

FILE=$1
while IFS= read -r line
do
    line2="${line} &"
    echo $line2
done <$FILE

私の入力ファイルには以下が含まれています。

message
sample
text

期待される出力

message &
sample &
text &

ただし、スクリプトを実行すると、次のような結果が表示されます。

 &ssage
 &mple
 &xt

最後に文字列を追加しないのはなぜですか?

答え1

 &ssage
 &mple
 &xt

問題は、入力ファイル(明らかにWindowsで生成された)にCRLF行の終わりがあることです。

修正するsed -i 's/\r//' file

答え2

問題は、入力テキストファイルがDOSテキストファイルであることです。これは、各行がキャリッジリターン文字で終わることを意味します。出力すると、この文字はカーソルを行の先頭に戻します。つまり、echo前のスペースを出力すると、行&の先頭に書き込まれます。

テキストファイルをUnixテキスト形式に変換するには、同様のツールを使用する必要がありますdos2unix

また、値を印刷するときにシェルコードから引用する際に問題が発生します$line2。変数拡張を引用しないため、シェルは値をスペース、タブ、および改行に分割して単語を生成します。これらの単語はechoワイルドカードパターンとして渡され、これらのファイル名に置き換えられます。たとえば、*上記の入力ラインを試してみてください。

場合によっては、このechoユーティリティが出力するデータを変更する傾向があるため(\nリテラル改行などに拡張)、入力リテラルデータを保存するにはこのユーティリティを使用する必要がありますprintf

シェルループからテキストを1行ずつ読み取ることも少し非効率的であり、次のようなことでより良い作業を実行できますsed

sed 's/$/ \&/' <"$1"

(行末をスペースとアンパサンドに置き換えます)

...またはawk

awk '{ printf "%s &\n", $0 }' <"$1"

(各行をスペースで出力して追加します&。また機能しますprint $0, "&")。

また見なさい:

答え3

私はこれを再現できません。

ローカルで実行して簡単に試すことができるバージョンも作成しました。https://www.onlinegdb.com/online_bash_shell

while IFS= read -r line
do
    line2="${line} &"
    echo $line2
done <<EOM
message
sample
text
EOM

出力

message &
sample &
text &

関連情報