intercambiar campos en columnas por patrón fijo (sí, no, no, sí)

intercambiar campos en columnas por patrón fijo (sí, no, no, sí)

Quiero generar la siguiente lista de páginas (para trabajos de imposición); (el número de páginas es variable, pero hago una muestra de mis necesidades usando una lista de 16 páginas, la lógica es la misma para listas más largas)

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

Escribí esto para el ciclo:

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 " " ","

que, sin embargo, produce:

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

y no la lista de páginas que quiero. Entonces, necesito, con awk u otros comandos, intercambiar campos en algunas columnas siguiendo este patrón (repitiendo cada 4 pares de páginas)

intercambiar campos

sin campos de intercambio

sin campos de intercambio

intercambiar campos

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

Al generalizar la lógica de esta imposición (necesito imponer una única copia de un libro A6 en un formato de página A4), escribí un guión más generalizado.

#!/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

sin embargo, solo puedo producir:

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

en lugar de derecho:

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

que paso aMultivalente.jar

Adjunto una imagen de la imposición correcta de un A6 sobre un A4 para mostrar la secuencia correcta de imposición.

ingrese la descripción de la imagen aquí

Lo que intento obtener es una forma de imponer un libro A6 completo en una página A4 enUNOfirma que consta en todas sus páginas (no la Imposición de 8 páginas), para cortar por la mitad la página A4, cerrar las dos mitades una sobre otra, obtener la hoja inversa, cortar por la mitad y aplicar pegamento en el borde izquierdo para aplicar la cubierta.

Para realizar esta tarea necesito repensar mi script desde cero o encontrar una manera de intercambiar campos en columnas mediante un patrón fijo (intercambiar, no intercambiar, no intercambiar, intercambiar) para corregir el orden incorrecto producido por mi script

EDITAR

resolvió el envío de la salida estándar del script a awk con esta sintaxis:

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

Respuesta1

El siguiente script es una forma mucho más clara de obtener el resultado que desea.

#!/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

Ejemplo

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

Reescribí tu guión porque hubo varios problemas con el original.

  • Usaste una sintaxis específica no shcompatible bash, así que corregí la línea shebang para que coincidiera.

  • Todo se puede hacer en estado puro bash. El uso de múltiples trinvocaciones externas awkes bcineficiente. En particular, debe saber que bashincluso los compatibles con POSIX shpueden realizar operaciones matemáticas internamente.

Respuesta2

Aquí hay un script que lo hace limpiamente (con suerte). No estoy familiarizado con los métodos de impresión/encuadernación, así que no estoy seguro de si la secuencia es correcta, pero ciertamente funciona desde el centro hacia afuera... Simplemente no No sé la secuencia de plegado/corte que necesita (más allá del ejemplo de 16 páginas)... He incluido un resultado de muestra de 24 páginas.

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  

producción

# 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

Este fragmento de código imprime una vista gráfica

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

producción

# 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
-------   -------

Respuesta3

Entiendo el deseo de derivar una fórmula, pero ¿no sería mucho más fácil y, por lo tanto, mejor, desde una perspectiva de mantenimiento, usar algo como esto?

#!/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' 

¿O no se repite el patrón así?

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

...

información relacionada