배쉬 : 명령 출력에서 ​​한 번에 한 줄을 읽는 방법은 무엇입니까?


49

을 사용하여 bash에서 명령의 출력을 읽으려고합니다 while loop.

while read -r line
do
    echo "$line"
done <<< $(find . -type f)

내가 얻은 출력

ranveer@ranveer:~/tmp$ bash test.sh
./test.py ./test1.py ./out1 ./test.sh ./out ./out2 ./hello
ranveer@ranveer:~/tmp$ 

이 후 나는 시도했다

$(find . -type f) | 
while read -r line
do
    echo "$line"
done 

하지만 오류가 발생했습니다 test.sh: line 5: ./test.py: Permission denied.

따라서 현재 전체 줄을 한 번에 비방한다고 생각하기 때문에 한 줄씩 읽는 방법은 무엇입니까?

필요한 출력 :

./test.py
./test1.py
./out1
./test.sh
./out
./out2
./hello

3
Bash FAQ 01- 유용한 정보와 피해야 할 함정에 대한 조언을 읽는 것이 좋습니다 .
jw013

while read부분에 대해서는 IFS 이해 및 관련 질문을 참조하십시오 .
Gilles 'SO- 악마 그만해

답변:


54

실수가있다, 당신은 필요 < <(command)하지<<<$(command)

< <( )A는 프로세스 대체 , $()A는 명령 치환<<<A는 여기 문자열 .


2
@RanRag $( )모든 것을 막으려 고 노력하지 마십시오 ! 이것이 명령 대체 구문이며 명령 출력을 사용하는 유일한 방법입니다. 파이프와 프로세스 대체 및 here-string은 다른 것들이며 모두 자연스럽게 구문이 다릅니다. 당신이하고있는 일을 정말로 모른다면 어쨌든 파일 이름을 파싱해서는 안됩니다.
jw013

감사합니다 Process Substitution. 자세한 내용을 읽어보십시오 .
RanRag

@ jw013 : 나는 배쉬 초보자입니다. 앞으로 당신의 제안을 내 마음에 두겠습니다.
RanRag

13

파일 이름에 개행 문자가 포함되는 것을 막을 수있는 것은 없습니다. find 에서 찾은 각 파일에 대해 명령을 실행하는 정식 방법 은 다음과 같습니다.

find . -type f -exec cmd {} \;

그리고 bash에서 일을 원한다면 :

find . -type f -exec bash -c '
  for file do
    something with "$file"
  done' bash {} +

또한 스크립트에서 "읽기"명령을 호출하는 표준 방법은 다음과 같습니다 (입력에서 추가 처리를 원하지 않는 경우).

IFS= read -r var

-rread백 슬래시 문자를 특수 문자 (분리 기호 및 줄 바꿈의 이스케이프 문자)로 처리하는 것을 중지 하고 IFS = 구분 기호 목록을 빈 문자열로 설정합니다 read(그렇지 않으면 공백 문자가 해당 목록에있는 경우 입력의 시작과 끝).

쉘에서 루프를 사용하는 것은 일반적으로 나쁜 생각입니다 (여러 도구가 하나 이상의 도구를 수백 번 연속 실행하는 대신 여러 도구를 동시에 동시에 작업하도록하는 쉘에서 작업이 수행되는 방식이 아님).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.