Bashを使用してファイルの最初の5行を繰り返す方法は?

Bashを使用してファイルの最初の5行を繰り返す方法は?

次のようにファイルの行を繰り返すことができます。

while read l; do echo $l; done < file

最初の5行だけを繰り返す方法はありますか?

答え1

以下を実行してください。

n=5
while IFS= read -ru3 line && (( n-- )); do
  printf 'Got this line: "%s"\n' "$line"
done 3< some-file

ただし、テキスト処理が関連している場合は、テキスト処理ツールを使用する方が良いです。

LC_ALL=C sed 's/.*/Got this line: "&"/;5q' < some-file

または:

awk '{print "Got this line: \""$0"\""}; NR == 5 {exit}' < some-file

または:

perl -lne 'print qq(Got this line: "$_"); last if $. == 5' < some-file

関連:

答え2

ファイルの最初の5行を繰り返す方法はいくつかあります。以下はいくつかあります。一般に、最後が最も効率的であることに注意してください。より良い方法このタイプの問題に対する解決策は、シェルスクリプトループを使用することです。

無差別代入:

{
    OIFS="$IFS" IFS=
    read -r line && printf "%s\n" "$line"
    read -r line && printf "%s\n" "$line"
    read -r line && printf "%s\n" "$line"
    read -r line && printf "%s\n" "$line"
    read -r line && printf "%s\n" "$line"
    IFS="$OIFS" 
} <file

ループ:

for ((i=1; i<=5; i++))
do
    IFS= read -r line
    printf "%s\n" "$line"
done <file

別のループは式が評価される前にすべての値のリストに展開されるため、小さい範囲に適しています(つまり、次に{1..5}変換されます)。1 2 3 4 5 今後実装する):

for i in {1..5}
do
    IFS= read -r line
    printf "%s\n" "$line"
done <file

ファイルの先頭のみが考慮されますが、このループ内に設定されているすべての変数に注意してください。アクセスできないそれしか

head -n5 file |
    while IFS= read -r line
    do
        printf "%s\n" "$line"
    done

ループをまったく使用しないでください

head -n5 file

sed 5q file

答え3

あなたはそれを使用することができますプロセスの交換、パイプを使用するのとは異なり、プロセスの置き換えにより、whilehead -n 5 fileループは現在のシェルで実行され、そのシェルで変数を設定/変更でき、そうでないとその環境に影響を与える可能性があります。 - サブプロセスまたはサブシェル(パイプなど)は、親環境に影響を与えることはできません。filehead -n 5 file

たとえば、

while read l; do printf '%s\n' "$l"; done < <(head -n 5 file)

printf代わりにシェルを使用する理由echoと、テキストを処理するためにシェルを使用しないという警告について説明します。スティーブンの答えこれはすでに完了しています。この回答のリンクを読んでください。

関連情報