다음 파일이 있다고 가정해 보겠습니다.
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
무엇을 바꿔야 하나요?
답변1
그리고 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
하지만 빈 줄은 건너뜁니다.새로운 팀IFS 공백 문자로서 해당 시퀀스는 1로 계산되며 선행 및 후행 시퀀스는 무시됩니다. zsh
and ksh93
(아님 )을 사용하면 특별한 처리 없이 개행 문자로 bash
변경할 수 있습니다 .IFS=$'\n\n'
뒤따라개행 문자(후행 공백 행 포함)는 항상 명령 대체에 의해 제거됩니다.
또는그리고read
(더이상 cat
):
#!/bin/bash
while IFS= read -r line; do
echo "tester: $line"
done < "$1"
여기에는 빈 줄이 유지되지만 개행 문자로 적절하게 구분되지 않으면 마지막 줄을 건너뜁니다.
답변2
(9년 후:)
제공된 두 답변 모두 끝에 개행 문자가 없는 파일에서는 실패합니다. 이는 마지막 줄을 효과적으로 건너뛰고 오류가 발생하지 않으며 재앙으로 이어질 것입니다(어려운 방법으로 배웠습니다 :).
지금까지 "Just Works"(bash 및 sh에서)로 찾은 가장 깨끗한 솔루션은 다음과 같습니다.
while IFS='' read -r LINE || [ -n "${LINE}" ]; do
echo "processing line: ${LINE}"
done < /path/to/input/file.txt
보다 심층적인 토론을 보려면 다음 StackOverflow 토론을 참조하세요.파일 끝에 개행 문자가 없는 경우 "읽을 때"(Bash)를 사용하여 파일의 마지막 줄을 어떻게 읽습니까?
참고: 개행 문자가 없는 경우 이 방법은 마지막 줄에 추가 개행 문자를 추가합니다.
답변3
피할 수 있다면 하지 마세요. 특히 텍스트 작업을 할 때는 더욱 그렇습니다.
대부분의 텍스트 유틸리티는 한 번에 한 줄씩 텍스트를 처리하도록 설계되었으며, 적어도 GNU 구현의 경우 효율적이고 정확하게 처리하며 오류 조건을 잘 처리합니다. 파이프라인을 통해 병렬로 실행한다는 것은 여러 프로세서를 활용하여 작업을 수행할 수 있음을 의미합니다.
여기:
<input.txt sed 's/^/tester /' > output.txt
또는:
<input.txt awk '{print "tester", $0}' > output.txt
자세한 내용은 다음을 방문하십시오.쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?
텍스트 처리와 관련이 없고 파일의 각 줄에서 몇 가지 명령을 실행해야 하는 경우 xargs
다음을 수행할 수 있는 GNU에 유의하세요.
xargs -rd'\n' -I@ -a input.txt cp -- @ @.back
예를 들어.
Bash 쉘을 사용하면 내장 명령을 사용하여 파일의 각 줄을 배열에 넣을 수 있습니다 readarray
.
readarray -t lines < input.txt &&
for line in "${lines[@]}"; do
do-some-non-text-processing-you-cannot-easily-do-with-xargs "$line" || break
done
POSIXly에서는 루프 내에서 닫는 다른 fd를 IFS= read -r line
사용하여 일부 입력에서 한 줄을 수 있습니다 .while read
while
IFS= read -r line <&3 ||
[ -n "$line" ] # to cover for an unterminated last line.
do
{
do-some-non-text-processing-you-cannot-easily-do-with-xargs "$line" ||
break # abort upon failure if relevant
} 3<&-
done 3< input.txt > output.txt
read -r line
읽는 줄에서 선행 및 후행 공백 문자를 제거합니다(변수에 있는 경우) $IFS
. 그러나 yash
쉘만 POSIX 요구 사항을 따릅니다. 대부분의 쉘에서는 공백과 탭으로 제한됩니다. ksh93 및 최신 버전에서는 bash
로케일에서 공백으로 처리되는 모든 단일 바이트 문자에 대해 이 작업을 수행합니다.
따라서 줄을 읽고 앞뒤 공백을 제거하려면 다음을 수행할 수 있습니다 IFS=$' \t' read -r line
. ksh93, yash1 또는 최신 버전 의 bash
.IFS=$' \t\r'
yash
구문 $'...'
은 아직 지원되지 않지만 해당 구문이 필요 합니다 IFS=$(printf ' \t\r')
.
답변4
새 줄로 끝나는지 여부에 관계없이 모든 줄을 읽으려면 다음을 수행하십시오.
cat "somefile" | { cat ; echo ; } | while read line; do echo $line; done
출처: 내 오픈 소스 프로젝트https://sourceforge.net/projects/command-output-to-html-table/