GNU/Linux >> Linux の 問題 >  >> Linux

cat を使用して、各行に区切り記号があるファイルを行ごとに読み取れないのはなぜですか

問題は cat にはありません 、 for でも それ自体をループします。それは逆引用符を使用しています。次のいずれかを書く場合:

for i in `cat file`

または(より良い):

for i in $(cat file)

または (bash で) ):

for i in $(<file)

シェルはコマンドを実行し、出力を文字列としてキャプチャし、$IFS の文字で単語を区切ります . $i に行を入力したい場合 、あなたは IFS をいじる必要があります または while を使用します ループ。 while 処理されるファイルが大きくなる危険性がある場合は、ループの方が適しています。 $(...) を使用したバージョンとは異なり、一度にファイル全体をメモリに読み込む必要はありません。 .

IFS='
'
for i in $(<file)
do echo "$i"
done

"$i" を囲む引用符 一般的には良い考えです。このコンテキストでは、変更された $IFS を使用して 、実際には重要ではありませんが、良い習慣は良い習慣です。次のスクリプトで重要です:

old="$IFS"
IFS='
'
for i in $(<file)
do
   (
   IFS="$old"
   echo "$i"
   )
done

データ ファイルの単語間に複数のスペースが含まれている場合:

$ cat file
abc                  123,         comma
the   quick   brown   fox
jumped   over   the   lazy   dog
comma,   comma
$ 

出力:

$ sh bq.sh
abc                  123,         comma
the   quick   brown   fox
jumped   over   the   lazy   dog
comma,   comma
$

二重引用符なし:

$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
   (
   IFS="$old"
   echo $i
   )
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$

IFS を使用できます フィールドセパレーターとして改行が必要な特定の変数:

IFS=$'\n'
for i in `cat file`
do
   echo $i
done

内部フィールド区切り文字 (IFS) の変更と組み合わせた for ループは、意図したとおりにファイルを読み取ります

入力用

abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma

IFS 変更と組み合わせた for ループ

old_IFS=$IFS
IFS=$'\n'
for i in `cat file`
do
        echo $i
done
IFS=$old_IFS

の結果
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma

Linux
  1. 巨大なファイルの線Xから線Yへの猫?

  2. Rmが読み取り専用ファイルを削除できるのはなぜですか?

  3. Busy Boxはファイルを1行ずつ読み取りますか?

  1. Lsでアンカー^$を使用できますか?

  2. inode でファイルを操作できないのはなぜですか?

  3. Linux の <conio.h> ヘッダー ファイルはどこにありますか? <conio.h> が見つからないのはなぜですか?

  1. ファイルを保存すると、メタデータはどこに移動しますか?

  2. 一部のシェル `read` ビルトインが `/proc` のファイルから行全体を読み取れないのはなぜですか?

  3. sudo を使用してファイルが存在するかどうかを確認するにはどうすればよいですか?