Felder in Spalten nach festem Muster vertauschen (ja, nein, nein, ja)

Felder in Spalten nach festem Muster vertauschen (ja, nein, nein, ja)

Ich möchte die folgende Seitenliste erstellen (für Ausschießarbeiten); (die Seitenzahl ist variabel, aber ich erstelle ein Beispiel für meinen Bedarf anhand einer Liste von 16 Seiten, die Logik ist für längere Listen dieselbe)

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

Ich habe dies für den Zyklus geschrieben:

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

das führt jedoch zu:

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

und nicht die Liste der Seiten, die ich möchte. Also muss ich mit awk oder anderen Befehlen die Felder in einigen Spalten nach diesem Muster austauschen (wiederholt sich alle 4 Seiten)

Felder vertauschen

keine Swap-Felder

keine Swap-Felder

Felder vertauschen

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

Um die Logik dieser Auferlegung zu verallgemeinern (ich muss eine einzelne Kopie eines A6-Buches auf ein A4-Seitenformat auferlegen), habe ich ein allgemeineres Skript geschrieben

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

Ich kann jedoch nur Folgendes produzieren:

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

statt rechts:

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

dass ich übergeheMultivalent.jar

Ich füge ein Bild der richtigen Aufteilung eines A6 über ein A4 bei, um die richtige Reihenfolge der Aufteilung zu zeigen

Bildbeschreibung hier eingeben

Ich versuche, ein ganzes A6-Buch auf eine A4-Seite zu bringen, inEINSSignatur, die aus allen Seiten besteht (nicht aus der 8-seitigen Aufstellung), um die A4-Seite in der Mitte durchzuschneiden, die beiden Hälften übereinander legen, das erhaltene umgekehrte Blatt in der Mitte durchschneiden und den linken Rand mit Klebstoff bestreichen, um den Umschlag anzubringen

Um diese Aufgabe auszuführen, muss ich entweder mein Skript von Grund auf überdenken oder einen Weg finden, Felder in Spalten nach einem festen Muster zu vertauschen (Vertauschen, kein Vertauschen, kein Vertauschen, Vertauschen), um die von meinem Skript erzeugte falsche Reihenfolge zu korrigieren.

BEARBEITEN

Das Senden der Standardausgabe des Skripts an awk wurde mit dieser Syntax gelöst:

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

Antwort1

Mit dem folgenden Skript können Sie die gewünschte Ausgabe viel sauberer erhalten.

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

Beispiel

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

Ich habe Ihr Skript neu geschrieben, da es mit dem Original mehrere Probleme gab.

  • Sie haben eine nicht shkompatible bashspezifische Syntax verwendet, daher habe ich die Shebang-Zeile entsprechend korrigiert.

  • Das Ganze kann in reinem durchgeführt werden bash. Die Verwendung mehrerer trAufrufe, eines externen awkund bcist ineffizient. Insbesondere sollten Sie wissen, dass bashund sogar POSIX-konforme shBerechnungen intern durchführen können.

Antwort2

Hier ist ein Skript, das es (hoffentlich) sauber erledigt. Ich kenne mich mit Druck-/Bindemethoden nicht aus, daher bin ich nicht sicher, ob die Reihenfolge richtig ist, aber von der Mitte nach außen funktioniert es auf jeden Fall … Ich kenne nur die Falt-/Schneidereihenfolge nicht, die Sie benötigen (über Ihr 16-seitiges Beispiel hinaus) … Ich habe ein Beispiel für eine 24-seitige Ausgabe beigefügt.

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  

Ausgabe

# 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

Dieser Codeausschnitt druckt eine grafische Ansicht

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

Ausgabe

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

Antwort3

Ich verstehe den Wunsch, eine Formel abzuleiten, aber wäre es nicht viel einfacher und daher aus Wartungssicht besser, so etwas zu verwenden:

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

Oder wiederholt sich das Muster nicht so:

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

...

verwandte Informationen