2014-06-18 7 views
1

소스 파일 내의 모든 파일과 폴더를 대상 폴더로 (재귀 적으로) 이동해야하는 bash 스크립트에서 작업하고 있습니다. 가능한 한이 견고하게하고, 잠재적 인 argument list too long - errors를 해결하기 위해 노력하는find를 사용하여 xargs를 통해 파일을 이동하는 경우 "mv : can not stat"오류가 발생합니다.

, 나는 (움직임 함께 효율적으로 그룹) xargs으로 파이프 find 명령을 (안전하게 이동 할 파일을 결정하는)를 사용하도록 선택했다. 공백이있는 잠재적 인 문제를 해결하기 위해 -print0-0도 사용하고 있습니다. 나는 다음과 같은 테스트 스크립트 작성했습니다

다음과 같이 몇 가지 이유로 보인다

#!/bin/bash 

# create test source file structure, and destination folder 
mkdir -p sourceDir/{subdir1,subdir\ with\ space\ 2} 
mkdir -p destDir 
touch sourceDir/subdir1/{a1.txt,noExtension1,file1\ with\ space.txt} 
touch sourceDir/subdir\ with\ space\ 2/{a2.txt,noExtension2,file2\ with\ space.txt} 

#move files/folders from source to destination 
find sourceDir -mindepth 1 -print0 | xargs -0 mv --target-directory=destDir 

이 작업 (파일이 이동 예) 하지만을 나는 수많은 오류를 얻을 :

mv: cannot stat `sourceDir/subdir with space 2/file2 with space.txt': No such file or directory 
mv: cannot stat `sourceDir/subdir with space 2/noExtension2': No such file or directory 
mv: cannot stat `sourceDir/subdir with space 2/a2.txt': No such file or directory 
mv: cannot stat `sourceDir/subdir1/file1 with space.txt': No such file or directory 
mv: cannot stat `sourceDir/subdir1/noExtension1': No such file or directory 
mv: cannot stat `sourceDir/subdir1/a1.txt': No such file or directory 

오류를 생성하지 않고 (내 스크립트에 표시된 소스 파일 용)이 작업을 수행 할 수 없습니까?

왜 파일과 폴더가 실제로 이동되기 때문에 이러한 오류가 생성되는 이유는 무엇입니까?

+0

찾기 명령을 'find sourceDir -mindepth 1 -exec mv "{}"--target-directory = destDir \;로 바꾸십시오. –

+0

위의 스크립트와 함께 사용하면 여전히 오류가 발생합니다. – Jonny

답변

1

에 전달되는 인수의 끝을 의미

$ find [...] -exec mv '{}' [...] ';' 

.

짧은 대답 :-maxdepth 1 태그가 누락되었습니다. 다음 명령은

find sourceDir -mindepth 1 -maxdepth 1 -print0 | xargs -0 mv --target-directory=destDir 
# as does 
find sourceDir -mindepth 1 -maxdepth 1 -exec mv --target-directory=destDir '{}' + 

긴 대답을 작동합니다

내 원래 find 명령은 각각의 모든 파일의 경로를 나열하고 그들 각자를 이동하려고했다. 최상위 폴더가 옮겨지면 파일/폴더를 아래로 옮길 필요가 없었습니다. 그러나 스크립트는 여전히 시도 중이었습니다!

아래 스크립트는 (실제로 동작을 수행하지 않고)이 방법을 보여줍니다 :

#!/bin/bash 

mkdir -p sourceDir/{subdir1/subsubdir1,subdir\ with\ space\ 2} 
touch sourceDir/subdir1/{subsubdir1/deeperFile.log,a1.txt,noExtension1,file1\ with\ space.txt} 
touch sourceDir/subdir\ with\ space\ 2/{a2.txt,noExtension2,file2\ with\ space.txt} 
touch sourceDir/rootFile.txt 

echo -e "\n--- Output of 'ls -1: sourceDir':" 
echo "$(ls -1 sourceDir)" 

echo -e "\n--- original incorrect attempt was trying to move each of the following:" 
find sourceDir -mindepth 1 

echo -e "\n--- working attempt only needs to move each of the top level files/folders, everything underneath any folders will get moved automatically" 
find sourceDir -mindepth 1 -maxdepth 1 

주는 출력 :

--- Output of 'ls -1: sourceDir': 
rootFile.txt 
subdir1 
subdir with space 2 

--- original incorrect attempt was trying to move each of the following: 
sourceDir/rootFile.txt 
sourceDir/subdir with space 2 
sourceDir/subdir with space 2/file2 with space.txt 
sourceDir/subdir with space 2/noExtension2 
sourceDir/subdir with space 2/a2.txt 
sourceDir/subdir1 
sourceDir/subdir1/file1 with space.txt 
sourceDir/subdir1/noExtension1 
sourceDir/subdir1/a1.txt 
sourceDir/subdir1/subsubdir1 
sourceDir/subdir1/subsubdir1/deeperFile.log 

--- working attempt only needs to move each of the top level files/folders, everything  underneath any folders will get moved automatically 
sourceDir/rootFile.txt 
sourceDir/subdir with space 2 
sourceDir/subdir1 
+0

또는'-type d '를 추가하여 최상위 디렉토리를 찾을 수 있습니다. 내 대답을 확인하십시오. –

+0

'-type d'를 사용하면 최상위 파일을 무시합니다. 또한 내 답변에 명시된 -maxdepth 1이 없으면 솔루션에 하위 하위 폴더가 계속 나열되며 다시 이동하지 못합니다. 자세한 내용은 업데이트 된 답변을 참조하십시오. – Jonny

+0

질문에, 당신은 디렉토리만을 언급했습니다. 그래서'-type d'를 추가했습니다 –

0

find 명령을 사용하여 직접 그렇게하지 않는 이유는 무엇입니까? {} 각 찾은 파일 및 ; 나는 그것을 sussed 한 mv

+0

'find '를 직접 사용하지 않는 이유에 대한 답으로 - mv로 find를 사용하면 개별 파일마다 mv 명령이 실행됩니다. 수천, 또는 수십만 개의 파일이 이동하면 곧 느려지거나 비효율적이게됩니다. xargs를 넘기거나 ('+'를'-exec '와 함께 사용하면 이것을 향상시킬 수 있습니다). 자세한 내용은이 답변을 참조하십시오. http://stackoverflow.com/a/11942775/1448678 – Jonny

0

을 기본적으로 상위 디렉토리와 명령의 시작을 찾을 수의 출력을, 다음 디렉토리가 포함되어 있습니다. 당신이 xargs 또는 -exec이 출력을 사용하는 경우

sourceDir/subdir1 
sourceDir/subdir1/a1.txt 
sourceDir/subdir1/noExtension1 
sourceDir/subdir1/file1 with space.txt 
sourceDir/subdir with space 2 
sourceDir/subdir with space 2/noExtension2 
sourceDir/subdir with space 2/file2 with space.txt 

은, 그것은 먼저 상위 디렉토리를 처리하고 그 내용 그 이후됩니다 : 당신의 directroy 구조에

간단한 find 명령 출력 다음과 같은 수 있습니다. 이 경우 명령이 잘 실행되고 모든 전체 sourceDir/subdir1 디렉토리를 destDir/subdire1로 이동합니다.그 후 sourceDir/subdir1/a1.txt 또는 sourceDir/subdir1/noExtension1과 같은 파일/디렉토리가 이미 destDir로 이동되었으므로 sourceDir에 파일/디렉토리가 없습니다.

이 사용을 피하려면 -depth 옵션을 사용하십시오. 귀하의 경우에는

-depth Process each directory's contents before the directory itself. 

당신은 DESTDIR에 최고 수준의 소스 디렉토리를 이동 -type d 옵션을 추가 할 수 있습니다.

find sourceDir -mindepth 1 -type d -print0 | xargs -0 mv --target-directory=destDir 

또는

find sourceDir -mindepth 1 -type d -exec mv -t destDir "{}" \+ 

그것은 당신의 문제를 해결합니다.

+0

입력 해 주셔서 감사하지만 여전히 작동하지 않습니다. 내 대답에 명시된 '-maxdepth 1'이 없으면 솔루션은 하위 하위 폴더를 나열하고 다시 하위 폴더를 이동하지 못하게됩니다. 자세한 내용은 업데이트 된 답변을 참조하십시오. – Jonny

+0

동의 함. '-maxdepth1'은보다 일반적인 것을 만들 것입니다. –