이러한 파일 이름을 기반으로 각 디렉터리에 파일을 배포하려면 어떻게 해야 합니까?

이러한 파일 이름을 기반으로 각 디렉터리에 파일을 배포하려면 어떻게 해야 합니까?

카메라 사진을 이름이 있는 파일에 저장합니다.

192.168.33.16_01_20220723150356205_MOTION_DETECTION.jpg

각 날짜의 각 파일을 별도의 디렉토리로 이동하고 싶습니다

이 명령을 찾았습니다

find | awk '{print $1, substr($1,20,8)}' 

파일 이름과 원하는 대상 디렉터리의 튜플을 인쇄합니다.

이 명령의 출력을 명령으로 파이프할 수 있나요?

mkdir -p $2; mv $1 $2

어떻게든? 와 함께 있을 수 있나요 xargs?

답변1

모든 파일을 동일한 디렉토리에 넣으면 매우 간단한 솔루션입니다.

for i in *; do mkdir "${i:17:8}" && mv "$i" "${i:17:8}"; done

답변2

awk프로그램을 수정하여 쉘 명령을 출력한 후 다음으로 파이프 할 수 있습니다 sh.

find * | awk '{
  date=substr($1,20,8)
  printf "mkdir -p %s; mv %s %s\n", date, $1, date
  }' | sh

위 코드는 파일 이름에 공백(또는 특수 쉘 문자)이 포함되어 있으면 제대로 작동하지 않지만 모든 것이 질문에 표시된 것과 같으면 제대로 작동합니다.

답변3

귀하의 예에서는 192.168.33.16_01_20220723150356205_MOTION_DETECTION.jpg날짜를 제공하는 & 표현을 제공 awk했지만 substr($1,20,8)이는 주어진 파일 이름과 일치하지 않습니다.

또한 IP는 변경될 수 있으며 192.168.33.16 및 192.168.133.116(및 192.168.3.6)과 같이 더 많은(또는 더 적은) 숫자를 가질 수 있으며 시작 위치 20으로 하드코딩하는 것은 좋지 않습니다.

따라서 분할에는 모든 IP 사례에 적용되는 구분 기호 "_"를 사용하는 것이 좋습니다.

이제 날짜가 있으면 8자만 가져오고 시간은 무시하려고 합니다. 가장 왼쪽에 있는 캐릭터들입니다.

또한 jpg 파일만 처리하고 디렉터리가 존재하지 않는 경우에만 mkdir을 생성하려고 합니다.

Perl을 사용하면 이 모든 것이 간단해집니다.



@files_list = <*_*_*.jpg> ; # Process only *.jpg files having atleast 2 "_"

for $one_file (@files_list) {
  @items = split("_",$one_file) ; # $items[0] = IP ; $items[2] = Date
  $D = substr($items[2],0,8) ; # take only 8 left most Characters from Date
  unless (-e "$D") {
    system ("mkdir $D") ; # mkdir when the Directory is not existing
  }
  system ("mv $one_file $D\\$one_file") ; # move file to Directory
}


이것은 이미 강력하지만 필요한 경우에 더 많은 검사를 추가할 수 있습니다(예: 파일 이름에 "_" 문자가 4개만 포함되어 있는지 확인 _MOTION_DETECTION하고 mkdir이 성공하는지 확인하고 mv가 성공하는지 확인). 이와 같은 향상된 기능은 Perl에서도 쉽게 구현할 수 있습니다!

사용법:
jpg 파일이 포함된 디렉터리에서 이 Perl 스크립트를 실행합니다.
지정된 기준과 일치하는 모든 jpg 파일이 날짜별로 해당 디렉토리로 이동됩니다.
다른 jpg 파일과 다른 모든 파일은 변경되지 않습니다.

답변4

제 생각에는 다음과 같이 넣을 수 있습니다.

mkdir -p $2; mv $1 $2

스크립트에서 스크립트를 실행 가능하게 만들고 파이프로 연결합니다.

find -type f -not -name script.sh | awk '{print $1, substr($1,20,8)}'|xargs ./script.sh

이렇게 하면 이미 작성한 내용을 사용할 수 있습니다.

또는스크립트가 필요하지 않으면 말한대로 xargs를 사용할 수 있습니다.

find -type f| awk '{print $1, substr($1,20,8)}'|xargs -l bash -c 'mkdir -p $1;mv $0 $1'

관련 정보