services.csvから第1フィールドのサービス名だけを取り出す。
重複を除き、アルファベット順に api、db、web と表示したい。
api,west,7
web,east,3
api,west,7
db,east,4
web,east,3
api,east,2適切なコマンドはどれか。
uniqは隣接する重複行をまとめます。そのため、先にsortして同じサービス名を並べる必要があります。sort -uでも同じ結果を得られます。
詳細解説
cut -d, -f1 services.csv | sort | uniq第1フィールドを抽出し、同じ名前を隣接させた後、uniqで重複行を除きます。
正しい選択肢です。cutが第1フィールドだけを取り出し、sortがapi、db、webをそれぞれ連続する位置へ並べます。最後にuniqが隣接した重複を1行へまとめます。
パイプは左の標準出力を右の標準入力へ渡すため、処理の順序そのものが正解条件になっています。
sort services.csv | cut -d, -f1全行を並べ替えて第1フィールドを切り出しますが、重複除去を行っていません。
誤りです。CSV全体を並べ替えた後に第1フィールドを取り出しますが、重複を削除する処理がありません。apiとwebが複数行のまま残ります。
また、全行をsortするため、第2・第3フィールドも並び順に影響します。必要な列を先に絞る方が処理意図も明確です。
cut -d, -f1 services.csv | uniq | sortuniqは隣接した同一行だけをまとめるため、元データで離れた重複が残ります。
誤りです。元データではapiやwebが離れた位置にも現れます。sort前のuniqは、離れている同一行を重複として扱いません。
その後でsortしても、すでに通過した重複行は削除されないため、apiとwebが複数残ります。
printf 'api\nweb\napi\n' | uniqapi
web
apicut -d, -f2 services.csv | sort -u第2フィールドを抽出するので、得られるのはeastとwestです。
誤りです。-f2は第2フィールドを指定するため、サービス名ではなくリージョンのeastとwestを取り出します。
sort -uの使い方自体は正しいものの、抽出するフィールドが要件と一致しません。コマンドの一部分だけでなく、パイプ全体の入出力を確認します。
実際に確かめる
一時的な検証環境で実行できる例です。
cut -d, -f1 services.csv | sort | uniq
# 短い別解
cut -d, -f1 services.csv | sort -u期待される結果
api
db
web理解のポイント
- cutの区切り文字とフィールド指定
- uniqの前にsortする理由
- sort -uという短縮方法
確認時の注意
- 確認環境:
- 途中結果を確認したいときは、パイプを一段ずつ実行します。
- LC_ALLなどのロケール設定により、文字列の並び順が変わる場合があります。
基礎のおさらい
cutのフィールド指定
-d,で区切り文字をカンマにし、-f1で第1フィールドを選びます。CSVの引用符や埋め込みカンマまで厳密に扱う用途には専用パーサーが必要です。
uniqは隣接行だけを見る
uniqはソート機能を持たず、連続した同一行をまとめます。そのため、一般的な重複除去ではsort | uniqの順にします。
sort -uという別解
sort -uは並べ替えと重複除去を一度に行います。目的が単純な一意化なら、cut ... | sort -uでも同じ結果です。