パンの受け取りリストを作る

LinuxBeginner
オンラインで実践に進む

はじめに

EARLY CRUMB には、土曜日の袋詰め担当が実際に使えるリストが必要です。支払い済みの注文がキャンセルされることも、有効な注文に複数の商品が必要なこともあります。正しい注文と全数量を残し、注文ごとの袋ラベルを引き渡すのが仕事です。

この新しいラボには、すべての元記録と並べ替え済みの支払い済み注文 ID ファイルがあります。前の VM のファイルは不要です。基本的なターミナル操作ができれば十分で、選択、並べ替え、結合のコマンドは使用時に説明します。アプリや汎用スクリプトは作りません。

ファイル操作には Workstation、記録、実リスト、ラベルの閲覧とダウンロードには Pickup Preview を使います。プレビューはファイルを読むだけで、キャンセル除外や数量修正を代行しません。

キャンセル済み注文を除外する

このステップでは、支払い済みで未キャンセルの注文 ID 集合を作ります。Pickup Preview から始めます。

実際の袋詰め判断から考える

Sample label を開き、注文 ID、顧客、商品数量がどのように袋ラベルになるか見ます。次に Records を開きます。P101 は Alex の注文でライ麦パン 2 個とオート麦クッキー 1 個が必要です。P102 も Alex ですが未払いです。P103 は支払い済みですが cancellations.tsv に含まれ、袋を用意してはいけません。

支払いとキャンセルは別の問いに答えます。今回の受け取り対象になるには、正確な支払い状態が paid で、ID がキャンセルに含まれない必要があります。

注文番号、顧客、商品数量を示す準備済みラベルの例

独立した作業領域を確認する

Workstation に切り替えます。pwd は現在のディレクトリを、cat はファイルを表示します。

pwd
/home/labex/project/pickup
cat paid-order-ids.txt
P101
P103
P104
P105

この並べ替え済みファイルはラボ側が提供します。P103 を含め、正確な支払い状態が paid の ID が入っています。もう一方の判断材料を読みます。

cat source/cancellations.tsv
order_id
P103

source/ は変更しません。work/ 内のファイルと最終的な pickup-list.tsv は作り直せます。ディレクトリを移動した場合は cd /home/labex/project/pickup で戻ります。

並べ替え済みの 2 集合を比較する

ここでの集合は異なる ID の一覧です。comm は並べ替え済みファイルを比較します。第 1 列は第 1 入力にだけある ID、第 2 列は第 2 入力だけの ID、第 3 列は共通 ID です。-23 は第 2、第 3 列を非表示にし、第 1 入力にあって第 2 入力にない ID だけを残します。つまり支払い済み ID からキャンセル ID を引く操作です。

LC_ALL=C はこのターミナルで並べ替えと比較の順序をそろえます。tail -n +2 は見出しを除き、sort -u は並べ替えて同一 ID 行を 1 つにします。パイプは出力を次のコマンドへ渡します。> は別の作業ファイルに保存し、再試行時は置き換えます。入力パスを出力先にも使わないでください。

export LC_ALL=C
sort -u paid-order-ids.txt > work/paid.sorted.txt
tail -n +2 source/cancellations.tsv | sort -u > work/cancelled-order-ids.txt
comm -23 work/paid.sorted.txt work/cancelled-order-ids.txt > work/eligible-order-ids.txt
cat work/eligible-order-ids.txt
P101
P104
P105

P103 が除かれ、ほかの支払い済み注文は残りました。未整列の入力という警告が出たら、上記の設定で両方の入力集合を作り直します。元記録から注文を削除したり、支払いの欠落を袋詰めの許可と見なしたりしないでください。

商品リストを作り実際の袋ラベルを開く

このステップでは対象 ID の全商品と数量を保ち、実際の引き継ぎ資料を使います。Workstation から始めます。

ID をすべての商品行に結び戻す

orders.tsv では 1 つの注文 ID が複数行に現れます。P101 には rye と oat の両方が必要です。対象 ID が 3 つでもパンが 3 個とは限りません。元の商品行とその数量をすべて残します。

表を読みます。

cat source/orders.tsv

4 フィールドは order_id、customer、item、quantity で、タブで区切られています。最初の行は見出しです。tail -n +2 は見出しだけを除きます。TAB=$(printf '\t') はタブをシェル変数に保存します。-t "$TAB" は sort と join にその区切りを指定し、二重引用符で 1 つの引数として渡します。sort -k1,1 -k3,3 は注文 ID、商品コードの順で並べ替え、4 フィールドを保持します。注文 ID フィールドだけの sort -u で商品表を置き換えないでください。

TAB=$(printf '\t')
tail -n +2 source/orders.tsv > work/orders.rows
sort -t "$TAB" -k1,1 -k3,3 work/orders.rows > work/orders.sorted.tsv

join は並べ替え済み入力の最初のフィールドを照合します。第 1 入力は対象 ID、第 2 入力は全商品行です。ここでは一致のみを出す既定動作が適しています。対象注文だけを残し、その注文に一致する商品行をすべて出力します。ID は一度だけ現れ、その後に顧客名、商品、数量が続きます。

join -t "$TAB" work/eligible-order-ids.txt work/orders.sorted.tsv > work/pickup.rows
cat work/pickup.rows
P101 Alex oat 1
P101 Alex rye 2
P104 Noor oat 2
P105 Jules oat 1
P105 Jules rye 1

上の隙間はタブです。3 注文に対して商品行は 5 行あります。ファイルを渡す前に P101 の異なる 2 商品と数量を確認します。

受け取る側に明確な形式を渡す

表示ツールには同じ 4 フィールドの見出しが必要です。printf は \t をタブ、\n を改行として出力します。> は出力先を新規内容で開始し、>> は見出しを消さずに追記します。この 2 コマンドを繰り返すと、行を重複追加する代わりに前の引き継ぎ内容を置き換えられます。

printf 'order_id\tcustomer\titem\tquantity\n' > pickup-list.tsv
cat work/pickup.rows >> pickup-list.tsv
cat pickup-list.tsv

合計だけでなく引き継ぎ内容を使う

Pickup Preview に切り替え、Pickup list を開きます。開いていた場合は再読み込みします。3 collection bags · 5 item lines · 7 pieces と表示されるはずです。合計は誤りの発見には役立ちますが、各人への中身が正しい証明にはなりません。

Alex の P101 を開き、Oat cookie 1 と Rye loaf 2 を確認します。All collection bags で戻り、P104 を開いて Noor の Oat cookie 2 を確認します。P105 は Jules に Oat cookie 1 と Rye loaf 1 を渡します。P102、P103、P106 には袋がないはずです。顧客名だけでこれらの関係は確認できません。

ブラウザーが対応していれば Print label で印刷ダイアログを開き、プレビュー後にキャンセルします。実機プリンターは不要です。リストに戻り Download the actual list を選びます。ダウンロードされるのは自作 TSV そのもので、事前計算された参考ファイルではありません。

形式エラーが説明されたら、Workstation で見出しとタブを確認し、作り直して再読み込みします。数量が違う場合は work/pickup.rows と注文元を比べます。表示ツールは黙って結果を直しません。

既存の袋を重複させず遅れた注文を加える

このステップでは完全な改訂入力スナップショットから引き継ぎ内容を作り直します。前と同じシェル設定の Workstation で始めます。

新しい入力を理解する

source/ の元ファイルは変更しません。source/late/ は 3 表すべての完全な後続スナップショットで、結果末尾に追記する数行の差分ではありません。新しい支払い済み注文 P107 は Aya のもので、オート麦クッキー 2 個が必要です。前のキャンセルも引き続き適用されます。

cat source/late/orders.tsv
cat source/late/payments.tsv

提供された paid-order-ids.txt は元スナップショットを表します。新注文を含めるには、後の支払い表から支払い済み集合を再計算します。grep $'\tpaid$' はタブと行末の完全な状態を選び、unpaid を除外します。cut -f1 は注文 ID を残し、sort -u は比較用の ID 集合を準備します。前の LC_ALL=C と TAB を使い、再接続した場合はここで復元します。

export LC_ALL=C
TAB=$(printf '\t')
tail -n +2 source/late/payments.tsv | grep $'\tpaid$' | cut -f1 | sort -u > work/paid.sorted.txt
tail -n +2 source/late/cancellations.tsv | sort -u > work/cancelled-order-ids.txt
comm -23 work/paid.sorted.txt work/cancelled-order-ids.txt > work/eligible-order-ids.txt

同じ規則を新しい完全スナップショットに適用できました。次に、照合する商品入力と出力先を作り直します。

tail -n +2 source/late/orders.tsv > work/orders.rows
sort -t "$TAB" -k1,1 -k3,3 work/orders.rows > work/orders.sorted.tsv
join -t "$TAB" work/eligible-order-ids.txt work/orders.sorted.tsv > work/pickup.rows
printf 'order_id\tcustomer\titem\tquantity\n' > pickup-list.tsv
cat work/pickup.rows >> pickup-list.tsv
cat pickup-list.tsv

商品行は元の 5 行と P107/Aya/oat/2 の計 6 行になるはずです。見出しは一度だけです。完全スナップショットから再構築するため、古い行全部をもう一度追加することはありません。

実際の新しい引き継ぎを確認する

Pickup Preview に切り替え、Pickup list を開いて再読み込みします。4 collection bags · 6 item lines · 9 pieces を確認します。P107 を開き、Aya の Oat cookie 2 を確認します。P101 を再び開き、2 商品の行が引き続き正しいことを見ます。キャンセルされた P103 と未払い P102 にラベルはありません。

既存の袋を重複させず Aya を加えた実際の改訂リスト

実際のリストをもう一度ダウンロードし、改訂した引き継ぎ内容と比べます。Records は背景として意図的に元スナップショットを残します。後の入力は source/late/ で読んだファイルです。古いブラウザーページは再実行失敗の証拠ではないので、比較前に再読み込みします。

合計が倍になったら 2 つの書き込みコマンドを見直します。> で新しい見出しを作ってから、>> で現在の行を追記する必要があります。P107 がなければ、支払いと商品行の両方が source/late/ 由来か確認します。作業ファイルを直して再生成し、本当の注文行の代わりに期待合計を書き込まないでください。

まとめ

並べ替え済み ID 集合を比較し、対象注文をすべての商品行に結び戻して、実際の受け取りリストと袋ラベルを作りました。完全な後続スナップショットにも同じ処理を行い、既存の袋を重複させませんでした。独立したワークショップチャレンジでは、異なる対象条件と材料に同じ方法を使います。