ゆるふわシェル問題 その1
全部で8問
そんなに難しくないはず
だいたい1コマンドで解ける
使う技術
問題
Q1. 以下のテキストファイルaに含まれる犬郎を太郎に直せ
問題の意図
sed
を使う
犬を太に変換するだけだと犬神さんも書き換わっちゃう点に注意する
tr
だとマルチバイト文字の置換がうまくいかない
答え
Q2 カレンダーの曜日、毎日休みがいいので月から金まで日曜日にしてください。
cal 2月 2020
日 月 火 水 木 金 土
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
問題の意図
複数の文字を sed
で置換する
sed
の y
コマンドか正規表現を使うのが簡単かなぁと思ってる
答え
解説
y
は置換対象と置換後を1文字ずつ対応して置換する
上のだと月は1文字目の日と対応して置換される
q2_2.shcal | sed -E '2s/[月火水木金]/日/g'
解説
-E
で拡張正規表現を有効にする
[月火水木金]
は月火水木金のいずれかの文字にマッチする
日
でいずれかにマッチしたものを日に置換する
末尾の g
は行内でマッチするすべてを置換する
これがないと月だけ置換して終わる
追記
2s///g
みたいに先頭に 2
って付けないと1行目の 2月
まで置換されてしまっていた
Q3 以下のテキストファイルaから山田太郎さんを抽出してください。表記のムラも考慮してください
a山崎太郎
山田太郎
ヤマダタロウ
山田たろう
山田 太郎
山田 太郎
山本太郎
山田一郎
問題の意図
単純に grep
するだけだとどれかを取りこぼすか余計なものが交じる
どうやって複数のテキストを抽出するか
答え
q3.shgrep -E "(山田|ヤマダ)( | )?(太郎|タロウ|たろう)" a
解説
-E
で拡張正規表現を有効にする
(山田|ヤマダ)
では山田かヤマダにマッチする
( | )
では半角スペースか全角スペースにマッチする
?
では直前の文字が1つ存在する場合としない場合にマッチする
(太郎|タロウ|たろう)
で太郎かタロウかたろうにマッチする
Q4 以下のCSVファイル(大嘘)の2列めを取り出してください
aID、名前、趣味
1、田中、野球
2、山本、サッカー
3、鈴木、バレー
問題の意図
cut
ではマルチバイト文字を区切り文字に指定できない
awk
を使う必要がある
答え
q4.shawk -F 、 '{print $2}' a
解説
-F、
で区切り文字に、を指定
$2
で2列目の文字を指定
Q5 以下の点数表の平均値を求めてください
aname,score
田中,89
山田,60
鈴木,75
村田,95
問題の意図
awk
で簡単な集計をする
平均値なので合計値を全体数で割る時に工夫が必要
awk
の NR
変数を割る時の全体数に使うとヘッダの行数も含まれてるので1引く必要がある
答え
q5.shawk -F , '{ total += $2 } END { print total / (NR-1) }' a
79.75
この辺の解説は awk
でググればいっぱいヒットするのでそっちで見て(なげっぱなし)
Q6 echoを使わずに寿司と標準出力してください
問題の意図
なんとなく
他の人はどういうアプローチするかなぁというのが気になっただけ
答え
Q7 以下のような階段状の文字列を出力してください
ヒアストリングはNGで!
a1
11
111
1111
11111
111111
問題の意図
繰り返し処理をどうやるか
awk
を使うのが一般的かなぁと思ってたけれど for
でもできると思う
答え
q7.shseq 6 | awk '{ s = ""; for (i=0; i<NR; i++) { s = s "1" } print s }'
Q8. /work ディレクトリの下に2019/01 〜 2020/12までのディレクトリを作成してください。月はサブディレクトリを切ってください
問題の意図
実務ですぐ使えるシェルが役立つシーンの一つだと思ってだした
ループ処理をどうやるか
mkdir
のオプションを知っているか
答え
q8.shmkdir -p /work/20{19,20}/{01..12}
解説
-p
で存在しない親ディレクトリごと一気に作成できる
{}
でブレース展開
{19,20}
は19と20の文字列を半角スペース区切りで作る
{01..12}
は01から12の文字列を半角スペース区切りで作る
これらのブレース展開はブレース展開と隣接する文字を合わせて展開する
例
shecho a_{01..12}
# a_01 a_02 a_03 a_04 a_05 a_06 a_07 a_08 a_09 a_10 a_11 a_12
これをそのまま touch
すれば空ファイルが作れる
mkdir
すればディレクトリが作れる
以上
余談
問題考えるの難しい!!!
cat, grep, sed, awk, 正規表現とメジャーどころは抑えた気がする
sort, uniqもよく使うけれど簡単な問題が思いつかなかった
forやwhile使うやつもあってよかったかなぁ
cut, join, trとかはチョット考えたけどお見送り
joinはオプション自体が複雑だしなぁ〜〜〜
実務オペレーションでよく使うコマンドとかで問題だしてみたいなぁ
nginxのアクセスログの調査とか
件数集計とソートとか
圧縮ファイルの操作とか
ファイルの探し方とか
trapとか
バックグラウンド処理と
日付処理とか
ファイル作成とか
ダミーファイル作成とか
なんかLPICの問題みたいだな・・・