【Linux】Shellスクリプト:while read line最後の行を読めませんか???
1930 ワード
一、Shellスクリプト:while read lineが最後の行を読めない問題
今日shellスクリプトを使用してパークbucket情報を処理すると、スクリプトでwhile read lineループを使用してファイルを行単位で読み込むと、最後の行まで処理できないことがわかりました.スクリプトは、コマンドラインの最初のパラメータで指定したファイルをwhileループで行単位で読み込み、データを処理して出力します.#!bin/bash
while read line
do
data=`...line...`
echo "${data}" >> $2.txt
done < $1
簡単なクエリー学習を経て、この問題の背景、原因、解決策を以下の第2章に整理します.
二、背景、原因及び解決方案
1、背景
コンピュータが登場する前に、使用するテレタイプライター(Teletype Model)は毎秒10文字を打つことができます.しかし、その問題は、1行を打った後に改行するのに0.2秒かかり、ちょうど2文字を打つことができることです.この0.2秒以内に新しい文字が伝わってくると、この文字は失われます.
そこで研究開発者は、各行の後ろに終了を表す文字を2つ追加する方法を考えた.「リターン」(Carriage Return)と呼ばれ、タイプライターに印刷ヘッドを左の境界に位置させるように伝えた.もう一つは「改行」(Linefeed)と呼ばれ、タイプライターに紙を1行下に移動するように伝えます.これが「改行」と「折り返し」の由来です.
コンピュータが発明された後、この2つの概念も採用されたが、その時はメモリが高く、一部の研究者は行の終わりに2文字を加えるのはもったいないと考え、1つ加えればいいと考え、分岐した.
UnixおよびUnixシステムでは、各行の末尾に「」、すなわち「」しかありません.Windowsシステムでは、各行の末尾が「」、「r」です.1つの直接的な結果は、Unixシステムの下のファイルがWindowsで開くと、すべての文字が1行になります.WindowsのファイルをUnixで開くと、各行の末尾に^M記号が1つ増える可能性があります.
Windowsの下に新しいファイルを作成し、最後の行には戻り文字や改行文字は追加されません.linuxの新しいファイルでは、最後の行に改行文字が1つ追加されます.
2、原因:
私のターゲットファイルはwindowsで作成されてサーバに転送されるので、while read lineでファイルを読み込むときに、ファイルの最後の行の後に改行がなければ、readが最後の行を読み込むときにファイル終了子EOFに遭遇したときにループが終了します.上のコードでは、$lineに最後の行の内容が格納されていますが、プログラムがこの行の内容を処理する機会がなくなり、最後の行が読み込めなくなりました.
3、方案一:
whileループを変更し、[-n${line}]]を増やします.これにより、ファイルが最後の行に達していない場合、-n$lineはテストされません.ファイルの終了(最後の行)に遭遇した場合も、$lineに内容があるかどうかをテストすることで処理を続行できます.#!bin/bash
while read line || [[ -n ${line} ]]
do
data=`...line...`
echo "${data}" >> $2.txt
done < $1
4、方案二:
原因を分析すると,本質的な原因はファイルフォーマットがunixではないためであり,スクリプトコードを変更することなく直接ファイルフォーマットを設定することで処理できることが分かった.# vim
vim target_file
# , dos unix
:set ff?
# unix ,
:set ff=unix
:wq
#!bin/bash
while read line
do
data=`...line...`
echo "${data}" >> $2.txt
done < $1
1、背景
コンピュータが登場する前に、使用するテレタイプライター(Teletype Model)は毎秒10文字を打つことができます.しかし、その問題は、1行を打った後に改行するのに0.2秒かかり、ちょうど2文字を打つことができることです.この0.2秒以内に新しい文字が伝わってくると、この文字は失われます.
そこで研究開発者は、各行の後ろに終了を表す文字を2つ追加する方法を考えた.「リターン」(Carriage Return)と呼ばれ、タイプライターに印刷ヘッドを左の境界に位置させるように伝えた.もう一つは「改行」(Linefeed)と呼ばれ、タイプライターに紙を1行下に移動するように伝えます.これが「改行」と「折り返し」の由来です.
コンピュータが発明された後、この2つの概念も採用されたが、その時はメモリが高く、一部の研究者は行の終わりに2文字を加えるのはもったいないと考え、1つ加えればいいと考え、分岐した.
UnixおよびUnixシステムでは、各行の末尾に「」、すなわち「」しかありません.Windowsシステムでは、各行の末尾が「」、「r」です.1つの直接的な結果は、Unixシステムの下のファイルがWindowsで開くと、すべての文字が1行になります.WindowsのファイルをUnixで開くと、各行の末尾に^M記号が1つ増える可能性があります.
Windowsの下に新しいファイルを作成し、最後の行には戻り文字や改行文字は追加されません.linuxの新しいファイルでは、最後の行に改行文字が1つ追加されます.
2、原因:
私のターゲットファイルはwindowsで作成されてサーバに転送されるので、while read lineでファイルを読み込むときに、ファイルの最後の行の後に改行がなければ、readが最後の行を読み込むときにファイル終了子EOFに遭遇したときにループが終了します.上のコードでは、$lineに最後の行の内容が格納されていますが、プログラムがこの行の内容を処理する機会がなくなり、最後の行が読み込めなくなりました.
3、方案一:
whileループを変更し、[-n${line}]]を増やします.これにより、ファイルが最後の行に達していない場合、-n$lineはテストされません.ファイルの終了(最後の行)に遭遇した場合も、$lineに内容があるかどうかをテストすることで処理を続行できます.
#!bin/bash
while read line || [[ -n ${line} ]]
do
data=`...line...`
echo "${data}" >> $2.txt
done < $1
4、方案二:
原因を分析すると,本質的な原因はファイルフォーマットがunixではないためであり,スクリプトコードを変更することなく直接ファイルフォーマットを設定することで処理できることが分かった.
# vim
vim target_file
# , dos unix
:set ff?
# unix ,
:set ff=unix
:wq