ファイルから行を読み、文字列を追加したいと思います。ところがちゃんと付いていませんね。
#! /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 &