나는라는 폴더가 /home/user/temps
487 개 폴더가 있습니다. 각 폴더에는 thumb.png라는 파일이 있습니다.
thumb.png라는 모든 파일을 별도의 폴더에 복사하고 원래 폴더를 기준으로 이름을 바꿉니다.
나는라는 폴더가 /home/user/temps
487 개 폴더가 있습니다. 각 폴더에는 thumb.png라는 파일이 있습니다.
thumb.png라는 모든 파일을 별도의 폴더에 복사하고 원래 폴더를 기준으로 이름을 바꿉니다.
답변:
여기 있습니다 :
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
줄 의 따옴표 는 파일 이름에서 공백과 줄 바꿈 등을 처리하는 데 중요합니다.
new_file/\/thumb
?
${VARIABLE/PATTTERN/REPLACEMENT}
값을 생성 VARIABLE
하지만 대체 텍스트로 패턴을 대체합니다. 여기서 패턴은 /thumb
( /
이렇게 보이지 않도록 이스케이프 처리해야하며 ${new_file//PATTERN/REPLACEMENT}
, 이는 첫 번째 발생 대체 대신 글로벌 대체가 됨) 대체 텍스트는 비어 있습니다.
이것은 임의로 깊은 하위 디렉토리에서 작동합니다.
$ find temps/ -name "thumb.png" | while IFS= read -r NAME; do cp -v "$NAME" "separate/${NAME//\//_}"; done
`temps/thumb.png' -> `separate/temps_thumb.png'
`temps/dir3/thumb.png' -> `separate/temps_dir3_thumb.png'
`temps/dir3/dir31/thumb.png' -> `separate/temps_dir3_dir31_thumb.png'
`temps/dir3/dir32/thumb.png' -> `separate/temps_dir3_dir32_thumb.png'
`temps/dir1/thumb.png' -> `separate/temps_dir1_thumb.png'
`temps/dir2/thumb.png' -> `separate/temps_dir2_thumb.png'
`temps/dir2/dir21/thumb.png' -> `separate/temps_dir2_dir21_thumb.png'
interessting 부분은 매개 변수 확장 ${NAME//\//_}
입니다. 의 내용을 취하고 NAME
모든 발생을 /
로 대체합니다 _
.
참고 : 결과는 작업 디렉토리 및 find의 경로 매개 변수에 따라 다릅니다. temps의 상위 디렉토리에서 명령을 실행했습니다. 교체 cp
로 echo
실험한다.
이 시도
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
.
mv -i ./A A/thumb.png ../tmp/.png
폴더의 경우 다음을 생성합니다 .-모든 파일은 ../tmp/.png로 끝납니다 (../tmp는 내 대상 디렉토리입니다).
find -type d
하고 출력을 볼 수 있습니다 . 그것은 당신이 기대하는 모든 디렉토리를 얻습니까? 그렇지 않은 경우 문제를 보여주기 위해 출력을 추가하십시오. 행운을 빕니다.
read dir
디렉토리 a\nb
a와 b 에서 단어 분할을 수행합니다 .
복사하려면 cp 명령이 필요하고 linux의 이름을 바꾸는 것은 파일을 이동하는 것과 동일하므로 mv 명령을 사용 하여 수행해야합니다 . Linux에서는 항상 다른 폴더에있는 경우 소스에서 대상 폴더까지 전체 경로를 지정해야합니다. 나는 복사와 같은 것이 될 것입니다.
cp /source_path/file /destination_path/
또는 이름을 바꾸거나 이동
mv /source_path/old_file /destination_path/new_name_file