ファイルの行をループする方法は?


61

このファイルがあるとしましょう:

hello
world
hello world

このプログラム

#!/bin/bash

for i in $(cat $1); do
    echo "tester: $i"
done

出力

tester: hello
tester: world
tester: hello
tester: world

forただし、空白を無視して各行を個別に繰り返したいと思います。つまり、最後の2行を次のように置き換えます。

tester: hello world

引用符for i in "$(cat $1)";を使用iすると、ファイル全体が一度に割り当てられます。何を変更すればよいですか?

回答:


69

forIFS

#!/bin/bash

IFS=$'\n'       # make newlines the only separator
set -f          # disable globbing
for i in $(cat < "$1"); do
  echo "tester: $i"
done

ただし、改行はIFSの空白文字であるため空の行はスキップされ、そのシーケンスは1としてカウントされ、先頭と末尾の行は無視されることに注意してください。zshし、ksh93(ないbash)、あなたはそれを変更することができますIFS=$'\n\n'が、すべてのことに注意して、改行のために特別に扱われるべきではなく、末尾(そのためには空行を末尾に含まれます)改行文字を常にコマンド置換により削除されます。

またはread(これ以上cat):

#!/bin/bash

while IFS= read -r line; do
  echo "tester: $line"
done < "$1"

空白行は保持されますが、改行文字で適切に区切られていない場合、最後の行がスキップされることに注意してください。


5
おかげで、<ループ全体ができるとは知りませんでした。今では完全に理にかなっているが、私はそれを見た
トビアスキンツラー

1
私が見IFS \ read -r line' in second example. Is really IFS = `必要?while read -r line; do echo "tester: $line"; done < "$1"
私の

4
@GrzegorzWierzowiecki IFS=は、先頭と末尾の空白の削除をオフにします。Inをwhile IFS= read..
ジル 'SO-悪であるのをやめる'

0

それが価値があることのために、私はそれを非常に頻繁に行う必要があり、の正確な使用方法を決して思い出せないwhile IFS= read...ため、bashプロファイルで次の関数を定義しました。

# iterate the line of a file and call input function
iterlines() {
    (( $# < 2 )) && { echo "Usage: iterlines <File> <Callback>"; return; }
    local File=$1
    local Func=$2
    n=$(cat "$File" | wc -l)
    for (( i=1; i<=n; i++ )); do
        "$Func" "$(sed "${i}q;d" "$File")"
    done
}

この関数は、最初にファイル内の行数を決定し、次にsed行ごとに行を抽出するために使用し、各行を特定の関数に単一の文字列引数として渡します。大きなファイルではこれは非常に非効率になると思いますが、これはこれまでのところ問題ではありませんでした(もちろん、この歓迎を改善する方法に関する提案)。

使用方法はかなり甘いIMOです。

>> cat example.txt # note the use of spaces, whitespace, etc.
a/path

This is a sentence.
"wi\th quotes"
$End
>> iterlines example.txt echo # preserves quotes, $ and whitespace
a/path

This is a sentence.
"wi\th quotes"
$End
>> x() { echo "$#"; }; iterlines example.txt x # line always passed as single input string
1
1 
1
1
1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.