전체 크기를 기준으로 이미지 그룹 추가

전체 크기를 기준으로 이미지 그룹 추가

이 패턴으로 이름이 지정된 수백 개의 이미지가 있습니다.

file-001.gif
file-002.gif
file-003.gif
...

Magick을 사용하여 총 크기가 950kb를 초과하지 않는 한 각 이미지 세트를 추가하고 싶습니다.

그런 다음 총 크기가 950kb 미만이면 다음 배치를 처리합니다.

이것이 쉘 스크립트에서 달성될 수 있습니까?

답변1

글쎄, 나는 이것이 내가 본 것 중 최악의 단 한 줄이라고 확신하지만 그것이 효과가 있을 것이라고 생각합니다. 느슨하게 기반https://askubuntu.com/questions/878948/how-do-i-generate-a-running-cumulative-total-of-the-numbers-in-a-text-file

sed $(echo 3+`ls -la | tee out/filesWithSizes.txt | awk '{print $5}' | awk '{total += $0; $0 = total}1' | sed 's/$/ < 950000/' | bc | grep -o '1' | wc -l`|bc )q out/filesWithSizes.txt | tail -n +4

이 광기를 설명하겠습니다.

ls -la모든 파일과 크기를 가져오는 데 사용됩니다 .

tee나중에 참조할 수 있도록 해당 정보를 저장하고 파이프라인에 저장하는 데 사용됩니다.

5열 인쇄용 awk(예: 크기)

more를 사용하여 awk누적 합계를 생성하고 각 디자인이 정렬되도록 보장합니다(나중에 중요해질 것입니다).

sed줄 끝을 바꾸는 데 사용되므로 < 950000기본적으로 문자열을 추가합니다.

bc이러한 표현식을 평가하고 부울 값(예: 0 또는 1)으로 변환하는 데 사용됩니다 .

grep -o1을 포함하는 줄만 인쇄하는 데 사용됩니다 .

누적 합계는 설계별로 정렬되므로 출력을 계산할 수 있고 함께 붙여넣을 수 있는 파일 수를 순서대로 알 수 있습니다.

이 부분은 으로 끝났습니다 wc -l. 처음에는 a 플래그 없이는 작동할 수 없었기 때문에 3 + 파일 목록 출력의 중지 지점을 얻기 위해 ls방금 계산한 숫자를 에코했습니다.bc

그런 다음 sed명령 대체를 사용하여 이전에 echo를 사용하여 계산한 줄 수 이후에 저장된 파일 목록의 내용과 크기 출력을 중지합니다.

tail마지막으로 해당 파일의 헤더가 아닌 첫 번째 줄에서 출력을 시작하는 데 사용됩니다 .

그러면 함께 연결할 수 있는 모든 파일 목록이 표시됩니다. 처리된 모든 파일을 이동하고 디렉토리에 더 이상 파일이 없을 때까지 거대한 oneliner를 계속해서 다시 실행하십시오.

답변2

일괄 추가해야 하는 이미지가 950kB보다 작은 개체로 끝나는 경우 단일 이미지 파일은 동일한 크기 구분을 초과할 수 없습니다.
첫 번째 단계: 해당 파일과 해당 크기를 모두 바이트 단위로 나열합니다.

$ find -L /path/to/directory -maxdepth 1 -type f -name "*.gif" -size -950k \
 -exec sh -c '\ls -Lgo "$1" | tr -s " "  | cut "-d " -f3,7-' sh {} \;

그러면 발견된 모든 파일의 이름과 해당 크기가 발견된 순서대로 한 번에 한 줄씩 화면에 인쇄됩니다. 주요 징후 find는 다음과 같습니다.

  • -L:심볼릭 링크를 따르고 링크 자체가 아닌 링크 대상에 대한 정보를 표시합니다. 이를 원하지 않으면 를 -H사용하십시오.
  • -maxdepth 1: 드롭될 수 있는 검색을 수행합니다.1수준, 떨어지는 것에서 /path/to/directory. 필요에 따라 번호를 수정합니다. 자세한 내용은 을 참조하세요 man find.

적어도 bash5.0 구현 에서는 find킬로바이트(kiB) 단위로 작동하는 것 같습니다. 즉, 위의 경우 950*1024바이트 이하의 크기를 가진 파일을 찾습니다. 컷오프 크기를 950KB(950000B)로 설정해도 문제 없습니다. 그냥 사용하세요 -size 927730c. Debian 배포판에서는 이 문제가 2016년에 해결된 것으로 보이므로 계속 사용할 수 있습니다 -size 950k.

"크기"모호한 속성일 수 있습니다. OP에 더 많은 정보가 부족하기 때문에 다음을 사용할 수 있다는 사실도 포함했습니다.할당된 총 블록 크기발견된 각 파일에 대해. 이것이 당신이 원하거나 필요한 것이라면 다음을 수행하십시오.

$ find -L /path/to/directory -maxdepth 1 -type f -name "*.gif" -size -950k \
  -exec sh -c '\ls -Ls -C1 "$1"' sh {} \;

여기서 얻는 크기 수치는 저장 매체의 블록 크기에 따라 달라집니다.

2 단계magick: 쉘 스크립트를 통해 batch_append.sh이전 출력을 한 번에 처리합니다 . 이미지 파일은 나열된 순서대로 첨부하되, 결과물의 무게는 950kB를 초과할 수 없습니다. 이 명령의 출력은 find다음과 같이 배열을 채우는 데 사용됩니다.

$ cat batch_append.sh

#!/usr/bin/bash

sdir=/path/to/directory
size=0
nas_idx=0    # next append start (nas) index (idx)
cnt=0
declare -a b

IFS=$'\n' read -d '' -a a < <(find -L "$sdir" -maxdepth 1 -type f -name "*.gif" -size -950k -exec sh -c '\ls -Lgo "$1" | tr -s " " | cut "-d " -f3,7-' sh {} \; 2>/dev/null)
num=${#a[@]}

for (( i=0; i<num; i++ )); do
    (( size+=$(echo "${a[$i]}" | cut "-d " -f1) ))

    if [ "$size" -gt 950000 ] ; then
        (( size-=$(echo "${a[$i]}" | cut "-d " -f1) ))
        (( i-=1 ))
        #echo "$size" for files from "$(( nas_idx+1 ))" to "$(( i+1 ))"  # testing
        #echo "${b[@]}"   # testing
        magick "${b[@]}" append appended_$(( nas_idx+1 ))_$(( i+1 )).gif
        nas_idx=$(( i+1 ))
        size=0  # reset 'size' variable to start new append batch
        cnt=0
        unset b
    else
        b[cnt]=$(echo "${a[$i]}" | cut "-d " -f2-)
        (( cnt++ ))
    fi

    if (( i==num-1 )); then
        # last append batch
        #echo "$size" for files from "$(( nas_idx+1 ))" to "$(( i+1 ))"  # testing
        #echo "${b[@]}"   # testing
        magick "${b[@]}" append appended_$(( nas_idx+1 ))_$(( i+1 )).gif
        unset b
    fi
done

printf '\n  %d files were processed.\n' "$num"
exit(0)

결론:

  • 실행하기 전에 스크립트를 실행 가능하게 만드십시오.chmod ug+x batch_append.sh
  • 스크립트를 한 번만 실행하면 됩니다.
  • 스크립트가 아직 전달되지 않았습니다 magick.
  • 프로덕션 환경의 경우 포함해야 할 문제가 많이 있습니다.
  • 호스트에 다중 코어가 있고 많은 수의 파일을 처리해야 하는 경우 병렬 실행을 예약하여 스크립트를 개선할 수 있습니다.
  • 파일은 도착하자마자 일괄 처리됩니다. 즉, findcmd가 파일을 계산할 때입니다. 이는 검색 플래그의 수와 이를 연속적으로 정렬하는 방법에 따라 달라집니다 find.

관련 정보