한 디렉토리에서 다른 디렉토리로 모든 파일 (숨김 포함)을 어떻게 이동합니까?


132

디렉토리의 모든 파일 (숨겨진 파일 포함)을 다른 디렉토리로 어떻게 이동합니까?

예를 들어, ".hidden"및 "notHidden"파일이있는 "Foo"폴더가있는 경우 두 파일을 "Bar"라는 디렉토리로 어떻게 이동합니까? ".hidden"파일이 "Foo"로 유지되므로 다음은 작동하지 않습니다.

mv Foo/* Bar/

직접 해보십시오.

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/


바, 나는 입력하기 전에 답변을 새로 고쳐야한다는 것을 알았습니다. 매우 유용한 링크.
Steven D

슬프게도,이 질문은 여기에서 SU로 이동해야한다고 말했기 때문에 여기에서 끝났습니다. 물론 SU에 이미 중복이있을 때 여기로 이동했습니다. :)
Michael Mrozek

개인적으로, * nix 관련 질문과 답변은 SU에서 주제를 벗어난 것으로 생각합니다. 현재의 규칙으로 우리는이 질문과 같은 두 가지 사이의 수많은 콘텐츠 충돌로 끝납니다.
코리 클라인

답변:


151

Zsh

mv Foo/*(DN) Bar/

또는

setopt -s glob_dots
mv Foo/*(N) Bar/

( (N)디렉토리가 비어 있지 않다는 것을 남겨 두십시오 .)

세게 때리다

shopt -s dotglob nullglob
mv Foo/* Bar/

Ksh93

디렉토리가 비어 있지 않다는 것을 알고있는 경우 :

FIGNORE='.?(.)'
mv Foo/* Bar/

표준 (POSIX) sh

for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done

mv명령이 성공하더라도 오류 상태를 반환 하게하려면 훨씬 간단합니다.

mv Foo/* Foo/.[!.]* Foo/..?* Bar/

GNU 찾기 및 GNU mv

find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +

표준 찾기

소스 디렉토리로 변경하지 않아도되는 경우 :

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "$@" "$0"' ../Bar/ {} + -type d -prune

다음은 bash, ksh93 및 zsh에서 도트 파일이 일치하는지 여부를 제어하는 ​​방법에 대한 자세한 내용입니다.

세게 때리다

dotglob옵션을 설정하십시오 .

$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero

더 유연한 GLOBIGNORE변수 도 있습니다. 콜론으로 구분 된 와일드 카드 패턴 목록을 무시하도록 설정할 수 있습니다. 설정되지 않은 경우 (기본 설정) 쉘은 설정되어 있으면 값이 비어있는 것처럼, 옵션이 설정되어 있지 않은 경우 dotglob처럼 작동합니다 .*. 매뉴얼의 파일 이름 확장 을 참조하십시오 . 퍼베이시브 디렉토리 .이며 패턴과 명시 적으로 일치 ..하지 않는 한 항상 생략 .됩니다.

$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one

Ksh93

FIGNORE변수를 설정하십시오 . 설정이 해제되면 (기본 설정), 쉘은 마치 값이 마치 것처럼 동작 .*합니다. 무시 .하고 .., 그들은 명시 적으로 (KSH의 93s + 2008-01-31 상태에서 수동 일치해야 .하고 ..항상 무시됩니다, 그러나 이것은 정확하게 실제 동작을 설명하지 않습니다).

$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero

도트 파일을 명시 적으로 일치시켜 패턴 에 도트 파일을 포함시킬 수 있습니다 .

$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero

디렉토리가 비어있는 경우 확장을 비우려면 N패턴 일치 옵션 ~(N)@(*|.[^.]*|..?*)또는을 사용하십시오 ~(N:*|.[^.]*|..?*).

Zsh

dot_glob옵션을 설정하십시오 .

% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero

.그리고 ..패턴이 최고의 일치하는 경우에도 일치되지 않습니다 .명시 적으로이.

% echo .*
..two .one

D glob 한정자를 사용하여 특정 패턴의 도트 파일을 포함 할 수 있습니다 .

% echo *(D)
..two .one none zero

N빈 디렉토리에서 확장을 비우려면 glob 한정자를 추가하십시오 *(DN).


참고 : 당신은 다른 순서에서 파일 이름 확장 결과 (예를 들어, 얻을 수 있습니다 none다음에 .one다음 ..two의 설정에 따라) LC_COLLATE, LC_ALLLANG변수를.


1
nullglob? 의미가 mv없는 명령을 (N)실행하는 것보다 명령 을 중단하는 것이 더 적절합니다 (fish, csh / tcsh, zsh (없는 ) 또는 failglob가있는 bash) mv /Bar/.
Stéphane Chazelas

1
귀하의 GLOBIGNORE 설명이 부정확하고 오해의 소지가 있다고 말씀드립니다. 비어 있지 않은 값으로 GLOBIGNORE을 설정하면 dotglob 켜고 그하게 .하고 ..당신이 나중에 떨어져 다시 dotglob 설정하더라도 (zsh을, 생선, pdksh 같은 및 파생 상품 같은 다른 합리적인 껍질처럼) 일치하지 않습니다. ( 및 GLOBIGNORE=:; shopt -u dotglob; echo .*출력되지 않음 ). 에 GLOBIGNORE 설정 또는 또는 같은 효과가 있습니다. ....:...:
Stéphane Chazelas

ksh93항상 무시 .하고 (작동하는 곳 )과 (더 이상 작동하지 않는 곳 ) ..에서 깨져있는 것처럼 보입니다 . 환경에서 FIGNORE의 가치를 얻는 것이 나쁘다는 것을 명심하십시오 . 예를 들어 env var는 혼란을 일으킬 수 있습니다. ksh93k+ksh93mksh93FIGNORE='!(..)'
Stéphane Chazelas

24
#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

에서 man bash

dotglob 설정하면 bash는 '.'로 시작하는 파일 이름을 포함합니다. 경로 이름 확장 결과.


경고에 따라이 명령은 디렉토리가 비어 있으면 명령이 실제로 의도 한대로 수행 되더라도 오류 코드를 리턴합니다.
Gilles

1
@Gilles, 오류는 mv해당 파일 Foo/*이 존재하지 않는다고 불평하는 것입니다 . 흥미롭게 Foo도 검색 가능하지만 읽을 *수 없으며 거기에 호출 된 파일이 있으면 오류가 발생하지 않으며 해당 파일은 이동하지만 디렉토리의 다른 파일은 이동하지 않습니다. bashfailglob더처럼 동작 있도록 옵션을 zsh, fish또는 csh/ tcsh및 글로브 대신-가 그대로 글로브를 떠나 그 가짜 행동 확장 할 수없는 경우 오류가 명령을 중단합니다.
Stéphane Chazelas

7

이 작업을 수행하는 간단한 방법 bash

mv {Foo/*,Foo/.*} Bar/

그러나 이것은 또한 디렉토리를 이동시킵니다.

숨김을 포함하여 모든 파일을 이동하고 디렉토리를 이동하지 않으려면 for 루프 및 테스트를 사용할 수 있습니다.

for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;


4

한 가지 방법은 다음을 사용하는 것입니다 find.

find Foo/ -type f -exec mv -t Bar/ {} \+

-type f파일을 찾는 find 명령을 제한합니다. 당신은 조사를해야한다 -type, -maxdepth그리고 -mindepth의 옵션은 find하위 디렉토리에 대한 계정에 명령을 사용자 정의합니다. 찾기에는 길지만 매우 유용한 매뉴얼 페이지가 있습니다.


3
Foo/하위 디렉토리 및 기타 파일이 아닌 일반 파일 만 이동 합니다.
Gilles

2

복사 명령을 사용해보십시오 cp:

$ cp -r myfolder/* destinationfolder

cp -r 재귀 복사를 의미하므로 모든 폴더와 파일이 복사됩니다.

remove 명령 rm을 사용하여 폴더를 제거 할 수 있습니다 .

$ rm -r myfolder

더보기 : 모든 파일을 디렉토리에서 다른 디렉토리로 이동 하십시오 .


2
많은 큰 파일을 이동할 때 가장 좋지는 않지만 작동 할 것 같습니다.
코리 클라인

별 대신 점을 사용한다면?
빈센트

1

Rsync는 또 다른 옵션입니다.

rsync -axvP --remove-source-files sourcedirectory/ targetdirectory

rsync에서 후행 슬래시가 중요 sourcedirectory/하고 디렉토리의 내용을 sourcedirectory참조하지만 디렉토리 자체를 참조하기 때문에 작동합니다.

이 방법의 단점은 rsync가 이동 후 디렉토리가 아닌 파일 만 정리한다는 것입니다. 따라서 빈 소스 디렉토리 트리가 남아 있습니다. 이에 대한 해결 방법은 다음을 참조하십시오.

rsync로 파일을 이동하고 디렉토리를 삭제 하시겠습니까?

따라서 이동 작업에는 최적이 아니지만 복사 작업에는 매우 유용 할 수 있습니다.


1

bash / fish에 대한 답변

와일드 카드를 사용하여 수행하는 방법은 다음과 같습니다.

.[!.]* ..?*일치 모든 숨김 파일을 제외 .하고..

.[!.]* ..?* *and를 제외한 모든 파일 (숨김 여부) 과 일치...

그리고이 질문의 특정 예에 대답하려면 cd foo && mv .[!.]* ..?* * ../bar

설명

.[!.]*하나의 점으로 시작하는 파일 이름과 그 뒤에 점 ( 선택적으로 뒤에 오는 문자열)을 제외한 모든 문자를 찾습니다. 이것은 충분히 가까우지만 같은 두 개의 점으로 시작하는 파일이 없습니다 ..foo. 이러한 파일을 포함하기 위해 ..?*두 개의 점으로 시작하는 파일 이름과 일치하는 문자, 선택적으로 문자열이 오는 파일 이름을 추가 합니다.

테스트

아래 명령을 사용하여 이러한 와일드 카드를 테스트 할 수 있습니다. 나는 bash와 fish에서 성공적으로 시도했습니다. 그들은 sh, zsh, xonsh에서 실패합니다.

mkdir temp
cd temp
touch  a  .b  .bc  ..c  ..cd  ...d  ...de
ls .[!.]* ..?*
# you get this output:
          .b  .bc  ..c  ..cd  ...d  ...de
# cleanup
cd ..
rm -rf temp

0

이동 명령에 사용할 파일을 선택하기 위해 역 따옴표로 찾아서 grep 할 수도 있습니다. 그것들을 mv로 전달하십시오.

즉, 숨겨진 파일

find Foo -maxdepth 1 | egrep '^Foo/[.]' # Output: .hidden

그래서

mv `find Foo -maxdepth 1 | egrep '^Foo/[.]'` Bar # mv Foo/.hidden Bar

선택한 숨김 파일 만 다음으로 이동합니다 Bar.

mv `find Foo -maxdepth 1 | egrep '^Foo/.'` Bar # mv Foo/.hidden Foo/notHidden Bar

'.'이후 Foo의 모든 파일을 Bar로 이동합니다. egrep 명령에서 대괄호없이 와일드 카드 역할을합니다.

^문자가 일치하는 라인의 처음부터 시작 보장합니다.

egrep패턴 일치에 대한 자세한 내용은 여기를 참조하십시오 .

maxdepth 1stop을 사용 하면 find가 서브 디렉토리로 들어 가지 않습니다.


0

이 답변 에서 영감을 얻었습니다 .

파일을 복사하지 않고 ...

rsync -ax --link-dest=../Foo/ Foo/ Bar

주의 사항 :

  • --link-dest경로는 DESTINATION에 대해 절대적이거나 상대적이어야합니다 ( Bar 예제에서)

  • /SOURCE ( Foo/예제) 뒤에 두어야합니다 . 그렇지 않으면 SOURCE 폴더의 내용 대신 SOURCE 폴더가 복사됩니다.


0

나는 이것이 bash에 잘 작동하고 쉘 옵션을 변경할 필요가 없다는 것을 발견했다.

mv sourcedir/{*,.[^.]*} destdir/

편집하다:

G-man이 언급했듯이, 원래의 대답은 posix를 준수하지 않으며 위의 ndemou의 대답과 거의 동일합니다. 이것은 단지 cd소스 디렉토리 에 들어 가지 않아도된다는 것을 의미합니다 . 그렇게 큰 변화는 아니지만 실제로 다릅니다.

예 : 이미 다음과 같은 레이아웃이 있다고 가정 해 봅시다.

 $ tree -a
.
├── destdir
└── sourcedir
    ├── ..d1
    ├── ..d2
    ├── ..double
    ├── file-1
    ├── file-2
    ├── .hidden-1
    ├── .hidden-2
    ├── ...t1
    └── ...t2

원래의 질문은 단일 마침표가있는 숨겨진 파일 만 언급했지만 이름 시작 부분에 마침표가 두 개 이상 있다고 가정 해 봅시다. 중괄호에 추가 표현식을 추가 할 수 있습니다. 그런 다음 실행할 수 있습니다

mv sourcedir/{*,.[!.]*,..?*} destdir/

이것은 다음으로 확장됩니다.

mv sourcedir/file-1 sourcedir/file-2 sourcedir/.hidden-1 sourcedir/.hidden-2 sourcedir/..d1 sourcedir/..d2 sourcedir/..double sourcedir/...t1 sourcedir/...t2 destdir/

이제 destdir 에있는 모든 파일을 볼 수 있습니다 :

 $ tree -a
.
├── destdir
   ├── ..d1
   ├── ..d2
   ├── ..double
   ├── file-1
   ├── file-2
   ├── .hidden-1
   ├── .hidden-2
   ├── ...t1
   └── ...t2
└── sourcedir

4.x에서 더 많은 추가 기능을 사용하여 bash에서 중괄호로 멋진 일을 할 수 있습니다. 좋은 예를 보려면 bash-hackers 를 확인하십시오 .


1
이것은 기본적으로 중괄호를 추가 한 것을 제외하고는 ndemou의 답변을 복제합니다 (설명하지 않고). 그러나 (1) 이름이로 시작하는 파일과 일치하지 않으며 ..(2) POSIX를 준수 하려면 !대신 대신 사용해야 합니다 ^. 즉  {*,.[!.]*}.
G-Man

@ G-Man, 죄송합니다. 그래서 당신은 정확하고 ndemou의 응답을 보지 못한 것에 대해 나쁜 것입니다. 그들은 거의 같은 것입니다. 1. 내 버전이 posix와 호환되지 않음을 지적 해 주셔서 감사합니다. 2. 괄호 확장을 사용하여 쉘이 조치를 수행하는 데 사용할 문자열 목록을 작성하고 있습니다. 이것은 또한 cd파일에 대해 작동하거나 모든 파일에 대한 경로를 표현하기 위해 동일한 파일 경로를 반복해서 작성하기 위해 소스 디렉토리 에 들어갈 필요가 없음을 의미 합니다. 나는 독자들에게 내가 말하는 것에 대한 더 나은 그림을 제공하기 위해 예제를 곧 업데이트 할 것이다.
cmndr sp0ck

0

를 들어 최소한의 리눅스 배포판, 다음 작업을해야한다. 먼저 기본 이동을 모두 수행하십시오 (숨겨진 파일이 누락 됨). 그런 다음, 모든 숨김 파일로 이동합니다 (등을 .하고 ..있는 윌 하지 실제로 이동).

mv /sourceDir/* /destinationDir 2> /dev/null
mv /sourceDir/.* /destinationDir 2> /dev/null

참고 : 보이는 내용이 없으면 첫 번째 명령은 오류 메시지를 생성합니다. 두 번째 명령은 것입니다 항상 움직이지 수 없다는 오류가 발생 .하고 ... 따라서 /dev/null(그림과 같이) 오류를 파이프하십시오 .

이것을 하나의 라이너로 필요하면 간단히 세미콜론과 결합하십시오.

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