Bash for 루프가 "순서가 잘못된" 여러 개의 echo 문을 실행합니다.

Bash for 루프가 "순서가 잘못된" 여러 개의 echo 문을 실행합니다.

Bash 스크립트가 있습니다.

for j in "$(ls -d */)"; do 
    echo "$j"
    echo "$j"
done

산출:

dir1/
dir2/
dir3/
dir1/
dir2/
dir3/

내가 출력하고 싶은 것은 다음과 같습니다.

dir1/
dir1/
dir2/
dir2/
dir3/
dir3/

어떻게 하면 이런 식으로 출력할 수 있나요?

(이것은 장난감 예입니다.진짜내가 원하는 것은 디렉토리에 CD를 넣고 뭔가를 한 다음 다시 CD를 넣는 것입니다. 문자열 연결을 사용하여 동일한 작업을 수행할 수 있다는 것을 깨달았지만 이 동작이 너무 혼란스러워서 다른 질문을 찾을 수 없습니다. 그래서 물어볼까 생각했어요. )

답변1

귀하의 루프는하나반복합니다. 이 반복에서 변수 j의 값 은 다음과 같습니다.

dir1/
dir2/
dir3/

그런 다음 두 번 출력합니다.

단일 문자열을 반복하기 때문에 변수는 이 값을 얻습니다 ls -d */.

하위 디렉터리를 반복하려면 다음을 사용하세요.

for dirpath in */; do
    printf '%s\n' "$dirpath"
    printf '%s\n' "$dirpath"
done

lsls즉 , 전혀 사용할 필요가 없습니다(시력검사오직).

cd각 반복마다 디렉토리에 들어가려면 서브 cd셸에서 수행하고 거기서 수행해야 하는 모든 작업을 수행하십시오. 이렇게 하면 cd현재 작업 디렉터리가 하위 쉘에 로컬이므로 돌아갈 필요가 없습니다 .

for dirpath in */; do
    ( cd -- "$dirpath" && some-command )
done

cd현재 작업 디렉토리를 변경해야 하는 경우에만 입력하면 됩니다 some-command. 대부분의 작업은 원래 작업 디렉터리에서 수행할 수 있습니다.

답변2

이는 수행 중인 출력을 구문 분석하는 ls좋은 방법이 아닙니다 .

하지만 그렇게 말하면서 귀하의 질문은 다음과 같이 인용됩니다.

rm -rf dir?
for j in 1 2 3; do mkdir dir$j; done
for j in $(ls -d */); do 
    echo "$j"
    echo "$j"
done
dir1//
dir1//
dir2//
dir2//
dir3//
dir3//

게시물의 따옴표를 사용하면 전체 출력이 ls따옴표로 묶이므로 다음과 같이 처리됩니다.논쟁, for루프가 한 번만 반복되도록 하고 전체 출력을 ls인수로 사용합니다. 귀하의 코드는 전체 출력을 두 번 인쇄합니다 ls.

예제를 작성하는 더 좋은 방법 ls은 다음과 같습니다.

find . -type d -maxdepth 1 -mindepth 1 -exec printf '%s\n%s\n' "{}" "{}" \;

관련 정보