'mv'의 가변 공간 처리

'mv'의 가변 공간 처리

다음 파일/디렉터리가 포함된 디렉터리가 있다고 가정해 보겠습니다.

google
apple
mozilla foundation   # a file with spaces
browsers

browsers그래서 파일을 디렉토리 로 옮기고 싶습니다 . 내가 작성한 스크립트는 다음과 같습니다.

for d in $(ls); do
    if ! [ "$d" == "browsers" ]; then
        mv "$d" "browsers"
    fi
done

그런 다음 갔지만 google얻었 습니다.applebrowsers

mv: cannot stat 'mozilla': No such file or directory
mv: cannot stat 'foundation': No such file or directory

분명히 문제는 변수의 공백입니다. 이 문제를 처리하는 올바른 방법은 무엇입니까?

물론, 이 작업을 수행하려면 더 우아한 한 줄 명령이 있어야 한다고 확신하지만 공백이 있는 변수를 어떻게 사용해야 하는지 알고 싶습니다.

답변1

하다아니요사용한:

for d in $(ls)

대신 이것을 사용하십시오:

for d in *

이를 사용할 때 두 가지 문제점은 $(ls)쉘이 결과를 $(ls)다음과 같이 적용한다는 것입니다.분사그리고경로명 확장. 당신이 생각하는 한 그것은 그렇습니다분사이로 mozilla foundation인해 mozilla및 가 됩니다 foundation.

를 사용하지 않는 이유에 대한 자세한 내용은 $(ls)다음을 참조하세요."뭐해 $(ls *.txt)?"

디렉토리에 숨겨지지 않은 파일이 없는 경우를 고려해야 하는 경우(이 경우는 루프에서 for i in $(ls)한 번의 패스를 수행하는 대신( *에서 제외) 루프에서 어떤 패스도 수행하지 않기 때문에 더 좋아 보일 수 있습니다.) 일치하지 않는 글로브로 확장하지 않도록 쉘에 지시하고 싶습니다.$ifor i in *zsh

  • zsh:for i in *(N)
  • ksh93:for i in ~(N)*
  • bash4.4+: f() { local -; shopt -s nullglob; for i in *; ...; done; }; f(이 옵션을 로컬로 사용하는 것이 강조됩니다 ( 기본 옵션과 유사한 동작 nullglob에 대해서는 이 옵션도 참조하십시오 )).failglobzsh
  • yash:(그런 다음 재설정합니다. 내가 아는 한 set -o nullglob로컬 범위 옵션이 없습니다)yash
  • 다른 셸에서는 항상 [ -e "$i" ] || [ -L "$i" ] || continue루프에 추가하여 파일이 존재하는지 확인할 수 있습니다.

답변2

ls결과를 구문 분석하지 않음, John1024의 답변 외에도 find.

LC_ALL=C find . ! -name . -prune ! -name '.*' -type f -exec mv -t /path/to/dest {} +

(이것은 GNU find옵션이 사용되어 glob 과 -t같은 숨겨진 파일을 건너뛰고 비정규 파일을 제외한다고 가정합니다. 목록은 정렬되지 않습니다( 또는 반대로 ). 이름이 이들로 시작하는 모든 파일은 올바르게 건너뛰어야 합니다 . 사용자의 로케일 유효한 문자에는 포함되지 않지만 이는 오류 메시지의 언어에 영향을 미칩니다.ls*ls*LC_ALL=C.

관련 정보