특정 유형의 파일을 이동하고 동일한 이름의 파일 이름을 바꿉니다.

특정 유형의 파일을 이동하고 동일한 이름의 파일 이름을 바꿉니다.

이것이 내가 달성하고 싶은 것입니다:

readpst 라이브러리를 사용 pst하여 파일을 별도의 파일로 변환합니다 .eml. 각 파일을 변환한 후 pst여러 하위 디렉터리가 중첩된 디렉터리가 생기고 각 디렉터리와 하위 디렉터리 .eml에는 1..n.

문제는 그것들을 하나의 디렉토리에 모두 넣어야 하는데 다음과 같이 이동하려고 하면 다음과 같습니다.

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

이름이 같은 항목을 찾고 다음으로 끝납니다.

mv: will not overwrite just created 

충돌하지 않도록 파일을 디렉토리로 이동하고 이름을 바꾸는 방법을 아는 사람이 있습니까?

답변1

GNU 구현에는 대상 파일이 이미 존재하는 경우 다른 이름으로 파일을 생성하는 옵션이 cp있습니다 . --backup=[CONTROL]백업 확장자를 구분하기 위해 물결표("~")를 사용하기 때문에 형식이 약간 보기 흉합니다.

귀하의 경우 유용한 CONTROL주장은 다음과 같습니다 numbered.

find . -name '*.zip' -exec cp --backup=numbered '{}' '/path/to/outputdir' \;

mv이 접근 방식을 따르는 경우 나중에 별도의 단계를 통해 원본 파일을 삭제해야 합니다. 저는 그러한 옵션을 알지 못하기 때문입니다 .

이 솔루션에서 내가 본 한 가지 문제는 어떤 파일이 어떤 디렉터리에서 왔는지 구별할 방법이 없다는 것입니다. 편집: 일부 사람들은 이 동작이 적절하고 브라우저의 기본 동작이라고 생각하지만(예를 들어 동일한 이름의 파일을 동일한 디렉토리에 여러 번 다운로드하는 경우) 이 경우 이러한 "백업"의 파일 확장자는 다르지만 번호도 매겨져 있습니다.

위의 내용 외에도 슬래시 구분 기호를 밑줄로 변경하는 등 각 파일 이름에 경로를 삽입할 수도 있습니다. 결과는 더 많은 정보를 제공하지만 오류가 발생할 여지가 많고 매우 길고 보기 흉한 파일 이름이 생성될 수 있습니다.

find . -name '*.zip' | while read filePath; do cp "$filePath" '/path/to/outputdir'/"$(echo "$filePath" | sed -e 's#^\\.##' -e 's#/#_#g')"; done

또한 실제로 밑줄이 포함된 파일은 이상하게 보일 수 있으며 파일 이름의 밑줄로 구분된 부분이 이전에 경로 이름의 일부였던 경우 모호성이 발생할 수 있습니다.

'/path/to/outputdir'!로 시작하는 명령 사이의 슬래시 문자는 "$(echo "$filePath" |...매우 중요합니다!

첫 번째 표현은 sed검색 트리의 상단이 점 문자로 시작하여 지정되면 숨김 파일이 생성되지 않도록 하는 것입니다. find두 번째는 경로 구분 기호 슬래시를 밑줄로 바꿉니다.

또한 이 솔루션은 확장성이 좋지 않습니다. 쿼리만 수정하려는 경우 심각한 결과를 피하기 위해 많은 변경을 수행해야 할 수도 있기 때문입니다 find. 예를 들어 find쿼리에 디렉터리도 포함되어 있으면 cp해당 행은 처리되지 않습니다. 다행히 이 경우 복제가 실패하고 오류 스트림에 메시지가 표시되기도 합니다. 파일 시스템의 콘텐츠를 덮어쓰는 것은 농담이 아닙니다!

관련 정보