태그 보관물: scripts

scripts

공백이있는 ‘for’루프에서 완전한 줄을 읽는 방법 실행하려고하는데 전체

for파일 루프 를 실행하려고하는데 전체 줄을 표시하고 싶습니다. 그러나 대신 마지막 단어 만 표시합니다. 나는 완전한 선을 원한다.

for j in `cat ./file_wget_med`

do
echo $j

done

실행 후 결과 :

Found.

내 데이터는 다음과 같습니다.

$ cat file_wget_med
2013-09-11 14:27:03 ERROR 404: Not Found.



답변

for공백, 탭 또는 줄 바꿈과 같은 공백이 있으면 루프가 분할됩니다. 따라서 IFS (Internal Field Separator) 를 사용해야합니다 .

IFS=$'\n'       # make newlines the only separator
for j in $(cat ./file_wget_med)    
do
    echo "$j"
done
# Note: IFS needs to be reset to default!


답변

for루프는 기본적으로 공백 (공백, 탭, 개행)에서 분리됩니다. 한 번에 한 줄씩 작업하는 가장 쉬운 방법 은 while read대신 바꿈 을 사용하여 루프 를 사용하는 것입니다.

while read i; do echo "$i"; done < ./file_wget_med

나는 당신의 명령이 한 줄에 한 단어를 뱉어 내기를 기대 합니다 (내 파일로 테스트 할 때 일어난 일입니다). 다른 일이 발생하면 그 원인이 무엇인지 잘 모르겠습니다.


답변

#!/bin/bash
files=`find <subdir> -name '*'`
while read -r fname; do
    echo $fname
done <<< "$files"

검증 된 작업, 원하는 라이너는 아니지만 우아하게 작업 할 수는 없습니다.


답변

다음은 Mitchell Currie의 답변에 대한 약간의 확장입니다. 부작용의 범위가 작기 때문에 좋아합니다. 변수를 설정할 필요가 없습니다.

#!/bin/bash
while read -r fname; do
    echo $fname
done <<< "`find <subdir>`"


답변

나는 이것을 다음과 같이 쓸 것이다.

cat ./file_wget_med | while read -r j
do
    echo $j
done

원본 스크립트에서 최소한의 변경이 필요하기 때문에 (를 사용하는 솔루션은 제외 IFS하지만 bash이 루프 제어문의 동작 을 수정 하지는 않습니다).


답변

맵 파일은 로하지 휴대용 인덱스 배열로 파일에서 라인을 읽을 수있는 편리한 방법입니다 읽을 수 있지만 약간 빠른. for 루프를 사용하면 서브 쉘 작성을 피할 수 있습니다.

#!/bin/bash

mapfile -t < file.txt

for line in "${MAPFILE[@]}"; do
    echo $line
done

파이프 라인을 사용할 때 while 루프를 서브 쉘에 넣습니다. while 루프 형 변수 내부의 변경 사항은 스크립트의 외부 부분으로 전파되지 않습니다.

예:

#!/bin/bash

a=0
printf %s\\n {0..5} | while read; do
  ((a++))
done
echo $a # 'a' will always be 0.

(더 나은 해결책) :

#!/bin/bash

b=0
while read; do
  ((b++))
done < <(printf %s\\n {0..5})

echo $b # 'b' equal to 6 (works as expected).


답변

Dandalf는 함수형 솔루션에 가까워졌지만 알 수없는 양의 입력 결과 find ~/.gdfuse -name '*'를 변수 에 할당하려고 시도해서는 안됩니다 ! 또는 적어도 배열 변수를 통해 그러한 일을 시도하십시오. 당신이 너무 게으르다 고 주장한다면! 여기 Dandalf의 솔루션은 위험한 조작없이 수행됩니다. 그리고 한 줄로

while read -r fname; do
  echo $fname;
done <<< `find ~/.gdfuse -name '*'