it-swarm-ko.tech

파일 줄을 반복하는 방법?

이 파일이 있다고 가정 해보십시오.

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은 공백을 무시하고 각 줄을 개별적으로 반복하고 싶습니다. 즉, 마지막 두 줄은

tester: hello world

for i in "$(cat $1)"; 따옴표를 사용하면 i에 전체 파일이 한 번에 할당됩니다. 무엇을 바꿔야합니까?

63
Tobias Kienzler

for IFS :

#!/bin/bash

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

그러나 빈 줄은 newline 이 IFS- 공백 문자이므로 순서는 1로 계산되고 앞과 뒤는 1로 계산됩니다. 무시되었습니다. zshksh93 (bash 아님), IFS=$'\n\n' 개행을 특수하게 처리하지 않으려면 모든 후행 개행 문자 (후행 빈 행 포함)는 항상 명령에 의해 제거됩니다. 치환.

또는 read (더 이상 cat 없음) :

#!/bin/bash

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

빈 줄은 유지되지만 줄 바꿈 문자로 올바르게 구분되지 않으면 마지막 줄을 건너 뜁니다.

76
wag

가치있는 것을 위해, 나는 그것을 아주 자주해야하며, 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
1
Jonathan H