web-dev-qa-db-ja.com

ファイルを1行ずつ読み取るBashwhileループ

ここで説明したいファイルを1行ずつ読み取る方法は2つあります。

#!/bin/bash    

while read line    
do    
    echo-e "$ line \ n"    
done <file.txt

そして

#!/bin/bash    
exec 3<file.txt

while read line    
do    
    echo-e "$ line \ n"    
done

したがって、最初のバージョンは正常に機能しますが、ファイルを使用してwhileループが機能するメカニズムがわかりません。しかし、私が理解している2番目のバージョンのメカニズム。しかし、ここでは、なぜハングして何も印刷されないのかわかりません。

11
Narek

最初のループは、doneの後のリダイレクトがループ全体に適用されるため機能します。したがって、readは、スクリプトの標準入力からではなく、ファイルから読み取られます。

2番目のバージョンは、readが標準入力であるファイル記述子0から読み取り、そこに何も入力していないためにハングします。 exec行は、ファイルから読み取るためにファイル記述子3をリダイレクトしますが、ファイル記述子3から読み取っていません。

次を使用して、2番目を救助することができます。

exec <file.txt

これで、指定されたファイルから標準入力が読み取られます。

9

これはあなたのために働くかもしれません:

exec 3<file.txt

while read -u3 line
do
    echo -e "$line \n"
done

-u3ファイル記述子3から読み取ります

echoにkshのprintコマンドのような補数スイッチがないのは不思議です。

4
potong

スクリプトに間違いはほとんどありません。

  1. $と変数名の間のスペース。 (悪い編集かもしれません)
  2. echo-eの間のスペース。 (悪い編集かもしれません)
  3. ファイルが開いているファイル記述子での読み取りについて言及します。記述子0でファイルを読み取っており、execは記述子3で実行されています。

このようなものでなければなりません-

#!/bin/bash    
exec 3<file.txt

while read line  
do
    echo -e "$line \n"
done <&3
3
jaypal singh

-u3は私の目的に最適です(次の行のみを読む)

#!/bin/bash

logs=(*Logs.txt)
[[ -e "${logs[0]}" ]] || exit 0

exec 3<"${logs[0]}"

while read -u3 line
do
        if [[ $(echo "$line"| grep -c SCSI_STATUS_CHECK_CONDITION) -eq 1 ]]; then
                read -u3 line
                echo "$line"
        fi
done
0
Cristian