고정된 패턴으로 열의 필드 교환(예, 아니요, 아니요, 예)

고정된 패턴으로 열의 필드 교환(예, 아니요, 아니요, 예)

(임포지션 작업을 위해) 다음 페이지 목록을 생성하고 싶습니다. (페이지 수는 가변적이지만 16페이지 목록을 사용하여 요구 사항에 대한 예를 만들었습니다. 긴 목록의 논리는 동일합니다.)

1,16
8,9
15,2
10,7
3,14
6,11
13,4
12,5

나는 루프를 위해 이것을 썼습니다:

for ((x=16, y=1, z=8, w=9;x>=4, y<=4, z>=12, w<=12;x--, y++, z--, w++)); do echo "$x $y;$z $w"; done | tr ";" "\n" | tr " " ","

그러나 이로 인해 다음이 생성됩니다.

16,1
8,9
15,2
7,10
14,3
6,11
13,4
5,12

내가 원하는 페이지 목록 대신. 따라서 awk 또는 다른 명령을 사용하여 이 패턴(4페이지마다 반복)에 따라 특정 열의 필드를 교체해야 합니다.

분야 교환

교환 필드 없음

교환 필드 없음

분야 교환

16,1 (swap: becomes: 1,16
8,9  (no swap: remains 8,9
15,2 (no swap: remains 15,2
7,10 (swap: becomes: 10,7
14,3 (swap: becomes: 3,14
6,11 (no swap: remains 6,11
13,4 (no swap: remains 13,4
5,12 (swap: becomes: 12,5

이 부과의 논리를 요약하기 위해(A4 페이지 형식에 A6 책의 단일 사본을 부과해야 함) 보다 일반적인 스크립트를 작성했습니다.

#!/bin/sh
pages=$1
halfpages="`let DIVISION=$pages/2; echo $DIVISION`"
incr="$(echo "scale=0; $halfpages+1" |bc -l)"
dividedby4="$(echo "scale=0; $pages/4" |bc -l)"
lastupperpage="$(echo "scale=0; $pages-$dividedby4" |bc -l)"
u="u"
for ((x=$pages, y=1, z=$halfpages, w=$incr;x>=4, y<=4, z>=$lastupperpage, w<=$lastupperpage;x--, y++, z--, w++)); do echo "$x$u $y$u;$z $w"; done | tr ";" "\n" | tr " " "," | tr "\n" ","
exit 0

하지만 내가 생산할 수 있는 것은 다음과 같습니다.

16u,1u,8,9,15u,2u,7,10,14u,3u,6,11,13u,4u,5,12

올바른 것 대신에:

1u,16u,8,9,15u,2u,10,7,3u,14u,6,11,13u,4u,12,5

나는 다음으로 넘어간다다중 가격 항아리

정확한 조판 순서를 보여드리기 위해 A4를 가로질러 A6을 정확하게 조판한 사진을 첨부했습니다.

여기에 이미지 설명을 입력하세요.

내가 얻으려는 것은 A6 책 전체를 A4 페이지에 강제로 넣는 방법입니다.하나모든 페이지의 서명이 포함되어 있습니다(8페이지 정판 아님). A4 페이지의 절반을 자르고 두 절반을 모아서 얻은 용지를 뒤집고 반으로 자르고 왼쪽 가장자리에 접착제를 발라 표지를 적용합니다.

이 작업을 수행하려면 스크립트를 처음부터 다시 생각하거나 고정 패턴(스왑, 스왑 없음, 스왑 없음, 스왑)을 통해 열의 필드를 스왑하여 스크립트에서 생성된 잘못된 순서를 수정하는 방법을 찾아야 합니다.

편집하다

다음 구문을 사용하여 스크립트의 표준 출력을 awk로 보내는 문제를 해결했습니다.

awk -F "," '{
    print $2 "," $1;
    getline; print;
    getline; print;
    getline; print $2 "," $1
}' 

답변1

다음 스크립트는 원하는 출력을 얻는 더 깔끔한 방법입니다.

#!/usr/bin/env bash

(($# == 0)) && {
    echo "Usage: $0 <page_count>"
    exit 1
} >&2

# nTotal = $1 rounded up to a multiple 8
nTotal=$(($1 + 7))
nTotal=$((nTotal - nTotal % 8))
nHalf=$((nTotal / 2))
nQuarter=$((nTotal / 4))

# print page numbers in groups of 4, 2 groups at a time
for ((x=0; x < nQuarter; x+=2)); do
    printf '%du,%du\n%d,%d\n' \
        $((x + 1)) $((nTotal - x)) $((nHalf - x)) $((nHalf + x + 1))
    printf '%du,%du\n%d,%d\n' \
        $((nTotal - (x + 1))) $((x + 2)) \
        $((nHalf + x + 2)) $((nHalf - x - 1))
done

$ ./imposition8 16
1u,16u
8,9
15u,2u
10,7
3u,14u
6,11
13u,4u
12,5

원본 스크립트에 몇 가지 문제가 있었기 때문에 귀하의 스크립트를 다시 작성했습니다.

  • sh호환되지 않는 특정 구문을 사용했기 bash때문에 일치하도록 shebang 줄을 수정했습니다.

  • 모든 것은 pure 로 수행될 수 있습니다 bash. 여러 tr통화를 사용하는 것은 외부 통화 awkbc비효율적입니다. 특히, bashPOSIX 호환 제품이라도 sh내부적으로 수학 연산을 수행할 수 있다는 점을 알아야 합니다 .

답변2

여기 깔끔하게 완성된 스크립트가 있습니다.(희망합니다).. 저는 인쇄/제본 방법에 익숙하지 않아서 순서가 맞는지 잘 모르겠지만 확실히 중앙에서 바깥쪽으로 작동합니다... 모르겠어요 필요한 접기/자르기 순서(16페이지 예제 이상)... 24페이지 출력 예제를 제공했습니다.

pages=${1:-16}
pagesPerSheet=4
sheets=$((  (pages/pagesPerSheet) 
          +((pages%pagesPerSheet)>0) ))
pagesTot=$((sheets*pagesPerSheet))

Ob=0               # overall begin
Ox=$((pagesTot+1)) # overall max 
Hb=$((Ox/2))       # 2nd Half begin
hx=$((Hb+1))       # 1st half max

for ((s=sheets;s>0;s-=2)) ;do
   printf '%su,%su,%s,%s,%su,%su,%s,%s%s' \
           $((Ob+=1)) $((Ox-=1)) \
           $((hx-=1)) $((Hb+=1)) \
           $((Ox-=1)) $((Ob+=1)) \
           $((Hb+=1)) $((hx-=1)) \
           $(((s>2)) && echo ,)
done; echo  

산출

# 16 page
1u,16u,8,9,15u,2u,10,7,3u,14u,6,11,13u,4u,12,5
# 24 page
1u,24u,12,13,23u,2u,14,11,3u,22u,10,15,21u,4u,16,9,5u,20u,8,17,19u,6u,18,7

이 코드 조각은 그래프 보기를 인쇄합니다.

Ob=0               # overall begin
Ox=$((pagesTot+1)) # overall max 
Hb=$((Ox/2))       # 2nd Half begin
hx=$((Hb+1))       # 1st half max

for ((s=sheets;s>0;s-=2)) ;do
   printf '%2su %2su | %2su %2su\n%2s  %2s  | %2s  %2s\n-------   -------\n' \
           $((Ob+=1)) $((Ox-=1)) $((Ox-=1)) $((Ob+=1)) \
           $((hx-=1)) $((Hb+=1)) $((Hb+=1)) $((hx-=1))
done

산출

# 16 page
 1u 16u | 15u  2u
 8   9  | 10   7
-------   -------
 3u 14u | 13u  4u
 6  11  | 12   5
-------   -------

# 24 page
 1u 24u | 23u  2u
12  13  | 14  11
-------   -------
 3u 22u | 21u  4u
10  15  | 16   9
-------   -------
 5u 20u | 19u  6u
 8  17  | 18   7
-------   -------

답변3

공식을 도출하려는 욕구를 이해하지만 유지 관리 관점에서 볼 때 다음과 같은 공식을 사용하는 것이 더 쉽지 않으므로 더 좋습니다.

#!/bin/bash
arr=(1 16 8 9 15 2 10 7 3 14 6 11 13 4 12 5)
for i in {0..3}; do 
    for n in ${arr[*]}; do 
        echo -n $((n+16*i))","
    done
    echo
done | sed -r 's/([^,]+,[^,]+),/\1\n/g' 

또는 패턴이 다음과 같이 반복되지 않습니다.

1,16
8,9
15,2
10,7
3,14
6,11
13,4
12,5

17,32
24,25
31,18
26,23
19,30
22,27
29,20
28,21

...

관련 정보