Linux 찾기 기능에서 찾은 파일을 복사하고 이름을 바꾸는 방법은 무엇입니까?

Linux 찾기 기능에서 찾은 파일을 복사하고 이름을 바꾸는 방법은 무엇입니까?

487개의 폴더가 있는 이라는 폴더가 있습니다 /home/user/temps. 각 폴더에는 Thumb.png라는 파일이 있습니다.

Thumb.png라는 이름의 모든 파일을 별도의 폴더에 복사하고 원본 폴더에 따라 이름을 바꾸고 싶습니다.

답변1

여기 있어요:

for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;

편집하다:

그건 그렇고, 일반적인 통념은 이렇게 하는 것이 find나쁜 생각이라는 것입니다. 단순히 쉘 확장을 사용하는 것이 더 안정적입니다. 또한 이것은 가설 bash이지만 안전한 가정이라고 생각합니다 :)

편집 2:

명확성을 위해 분석하겠습니다.

# shell-expansion to loop specified files
for file in /home/user/temps/*/thumb.png; do

    # replace 'temps' with 'new_folder' in the path
    # '/home/temps/abc/thumb.png' becomes '/home/new_folder/abc/thumb.png'
    new_file=${file/temps/new_folder};

    # drop '/thumb' from the path
    # '/home/new_folder/abc/thumb.png' becomes '/home/new_folder/abc.png'
    cp "$file" "${new_file/\/thumb/}";
done;

${var/Pattern/Replacement}자세한 공사정보를 확인 하실 수 있습니다.여기.

이 줄의 따옴표는 cp파일 이름의 공백, 줄 바꿈 등을 처리하는 데 중요합니다.

답변2

이 솔루션은 하위 디렉터리와 하위 디렉터리의 파일을 "평면화"하여 모두 하나의 큰 디렉터리에 상주하도록 합니다. 새 파일 이름은 원래 경로를 반영합니다. 예를 temps/dir/subdir/thumb.png들어 가 됩니다 newdir/temps_dir_subdir_thumb.png.

find temps/ -name "thumb.png" |
  while IFS= read -r f do
    cp -v "$f" "newdir/${f//\//_}"
  done

디렉터리 tempsnewdir존재해야 합니다. 그리고 temps명령은 및 의 상위 디렉터리에서 실행되어야 합니다 newdir.

이 명령은 한 줄로 완료할 수도 있습니다.

find temps/ -name "thumb.png" | while IFS= read -r f; do cp -v "$f" "newdir/${f//\//_}"; done

;개행 문자가 있는 세미콜론( )에 유의하세요.


예제 출력

$ find temps/ -name "thumb.png" | while IFS= read -r f; do cp -v "$f" "newdir/${f//\//_}"; done
`temps/thumb.png' -> `newdir/temps_thumb.png'
`temps/dir3/thumb.png' -> `newdir/temps_dir3_thumb.png'
`temps/dir3/dir31/thumb.png' -> `newdir/temps_dir3_dir31_thumb.png'
`temps/dir3/dir32/thumb.png' -> `newdir/temps_dir3_dir32_thumb.png'
`temps/dir1/thumb.png' -> `newdir/temps_dir1_thumb.png'
`temps/dir2/thumb.png' -> `newdir/temps_dir2_thumb.png'
`temps/dir2/dir21/thumb.png' -> `newdir/temps_dir2_dir21_thumb.png'

확실하지 않은 경우 에 추가하여 echo실행될 cp내용을 확인하세요.

find  temps/ -name "thumb.png" | while IFS= read -r f; do echo cp -v "$f" "newdir/${f//\//_}"; done

설명하다

이 작업은 다음을 사용하여 수행할 수 있습니다.매개변수 확장: ${f//\//_}. 변수의 내용 f(경로와 파일 이름 포함)을 가져와 각 항목 /_.

이것은 어리석은 텍스트 검색 및 교체입니다. 두 개의 서로 다른 파일이 동일한 이름으로 끝나는 경우 파일 중 하나를 덮어쓰게 됩니다.

예를 들어, 두 개의 파일 temps/dir/thumb.pngtemps/dir_thumb.png. 두 파일 모두 이름이 temps_dir_thumb.png.로 변경되므로 하나의 파일이 손실됩니다. 손실되는 파일은 find디스크에서 발견된 순서에 따라 다릅니다.

의무적인 현학적인 경고: 파일 이름에 개행 문자가 포함되어 있으면 이 명령이 심하게 충돌합니다.

답변3

oneliner 명령에서 파일을 찾고, 복사하고, 이름을 바꿀 수 있습니다.-sh 실행:

find /home/user/temps -name thumb.png \
-exec sh -c 'cp "{}" "$(basename "$(dirname "{}")")_$(basename "{}")"' \;

(추가 내용은 "복사된 파일을 공백으로 처리하는 것입니다.)

옵션 2- with xargs(실행하기 전에 각 명령을 인쇄할 수 있음):

find /home/user/temps -name thumb.png \
| xargs -I {} --verbose sh -c 'cp "{}" "$(basename "$(dirname "{}")")_$(basename "{}")"'

sh -c cp "temps/thumb.png" "$(기본 이름 "$(dirname "temps/thumb.png")")_$(기본 이름 "temps/thumb.png")"

sh -c cp "temps/dir one/thumb.png" "$(basename "$(dirname "temps/dir one/thumb.png")")_$(basename "temps/dir one/thumb.png") "

sh -c cp "temps/dir two/thumb.png" "$(basename "$(dirname "temps/dir two/thumb.png")")_$(basename "temps/dir two/thumb.png") "

답변4

이 시도

mkdir /home/user/thumbs
targDir=/home/user/thumbs

cd /home/user/temps

find . -type d | 
 while IFS="" read -r dir ; do
   if [[ -f "${dir}"/thumb.png ]] ; then
     echo mv -i "${dir}/thumb.png" "${targDir}/${dir}_thumb.png"
   fi
done

편집하다

디렉터리 이름에 공백 문자가 포함된 경우를 대비해 따옴표를 추가했습니다.

나도 이렇게 바꿨어.오직실행할 명령을 인쇄합니다. 스크립트의 출력을 확인하여 모든 파일/경로 이름이 올바른지 확인하십시오. 실행하려는 명령에 문제가 없다고 확신하면 해당 명령을 삭제하십시오 echo.

관련 정보