【自習】「第59回シェル芸勉強会」の解答例
概要
- イベント名: jus共催 第59回レンキューベリーマッチシェル芸勉強会
-
開催日: 2022年4月29日(金)
- 参考リンク:
- アナウンスページ: https://usptomo.doorkeeper.jp/events/135281
- 午前の部資料: https://umidori.github.io/shellgei-59th-am/
- 午前の部Youtubeライブ配信録画: https://www.youtube.com/watch?v=5XtmG6X8i0w
- 午後の部Youtubeライブ配信録画: https://www.youtube.com/watch?v=M_BWFRIk_Kw
環境
次のように貧弱な作業環境ですので、Q4以降では2020.tar.bz2
の代用として、入っているファイル数が10分の1である2020_mini.tar.bz2
を使って解答しました。
$ neofetch
_,met$$$$$gg. mitsuhisa@debian
,g$$$$$$$$$$$$$$$P. ----------------
,g$$P" """Y$$.". OS: Debian GNU/Linux 11 (bullseye) i686
,$$P' `$$$. Host: FMVNF40Y
',$$P ,ggs. `$$b: Kernel: 5.10.0-14-686-pae
`d$$' ,$P"' . $$$ Uptime: 1 hour, 41 mins
$$P d$' , $$P Packages: 3603 (dpkg)
$$: $$. - ,d$$' Shell: bash 5.1.4
$$; Y$b._ _,d$P' Resolution: 1280x800
Y$$. `.`"Y$$$$P"' DE: Xfce 4.16
`$$b "-.__ WM: Xfwm4
`Y$$ WM Theme: Default
`Y$$. Theme: HighContrast [GTK2/3]
`$$b. Icons: gnome [GTK2/3]
`Y$$b. CPU: Intel Celeron M 530 (1) @ 1.729GHz
`"Y$b._ GPU: Intel Mobile 945GM/GMS, 943/940GML Express
`""" Memory: 493MiB / 2005MiB
Q1
先に下記コマンドでデータをダウンロード
wget https://github.com/ryuichiueda/ShellGeiData/raw/master/vol.58/nums.gz
まず、前回使ったnums.gz
のデータを使い、次のようにyoko
というファイルを作ってください。
zcat nums.gz | tr '\n' ' ' > yoko
yoko
から、87654321番目のデータを速い方法で出力してください。
A1
$ time tr ' ' '\n' <yoko | tail -n+87654321 | head -n1
480564
real 0m3.895s
user 0m2.270s
sys 0m1.503s
Q2
nums.gz
のデータについて、逆順に行番号をつけてください。様々な方法を考えて、時間を測ってみましょう。データが1億行あるという情報は使って構いません。
A2
$ time paste <(tac <(seq 100000000)) <(zcat nums.gz) >/dev/null
real 0m48.515s
user 0m25.826s
sys 0m2.205s
Q3
nums.gz
のデータについて、漢数字を除去して数字順に昇順にソートしてください。展開する処理もワンライナーの中に入れてください。自身の環境で速くできる方法を考えましょう。(終わらない場合は1万〜1千万行あたりで試してみましょう。)
A3
$ time (zgrep -E '^[0-9]*$' nums.gz >/tmp/A3 && LANG=C sort -mn /tmp/A3 >/dev/null)
real 1m0.003s
user 0m52.074s
sys 0m5.141s
Q4
Q4小問1
2020.tar.bz2
をtar -jxvf 2020.tar.bz2
で展開して2020
というディレクトリに入り、最もサイズの大きいファイルを探してください。
Q4小問2
2020.tar.bz2
を展開せずに最もサイズの大きいファイルを探してください。
A4
A4小問1
$ time ls -Sl | head -n2
合計 209388
-rw-r--r-- 1 mitsuhisa mitsuhisa 7967 11月 9 2020 fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20201109_103258.5744
real 0m1.609s
user 0m0.989s
sys 0m0.581s
A4小問2
$ time tar -jtvf 2020_mini.tar.bz2 | LANG=C sort -k3,3nr | head -n1
-rw-r--r-- ueda/ueda 7967 2020-11-09 10:33 2020/fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20201109_103258.5744
real 0m19.208s
user 0m16.582s
sys 0m2.068s
Q5
2020.tar.bz2
をtar -jxvf 2020.tar.bz2
で展開して2020
というディレクトリに入り、次の作業をしてください。
Q5小問1
ファイル名のhoge.cgi
のhoge
の部分に対応するディレクトリを2020
の下になるべく速いワンライナーで作ってください。
Q5小問2
各ファイルを対応する名前のディレクトリに振り分けてください。最初は10000ファイルずつ移動してみましょう。
A5
A5小問1
$ time ls -f | cut -d. -f1 | sort -u | xargs mkdir
real 0m0.288s
user 0m0.174s
sys 0m0.108s
# 確認
$ find . -type d
.
./fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x
./full_search
./index
./key
./last_articles
./link_keywords
./rank_articles
./tagcloud
A5小問2
$ time find . -type d | sed -E 's|^./?||;s|.+|mv &.* &/|' | sh
real 0m3.420s
user 0m0.523s
sys 0m2.745s
# 確認
$ ls -1 fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x/
fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20200812_215032.20591
fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20200815_214913.2495
fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20201109_103258.5744
fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20201128_094948.31088
fetch_1dXiKr0hEn3Vc5b7PAA8FsMT1iaAUz9x.cgi.20201229_222407.21142
Q6
2020.tar.bz2
をtar -jxvf 2020.tar.bz2
で展開して2020
というディレクトリに入り、ログのなかで使われているコマンド(+ hoge
や++ hoge
)の数を数え、多いものから表示してください。コマンドのふりをした変数などが混ざらないように注意してください。
A6
$ grep -Erh '^\+{1,2} [^ =]+' . | awk '{n[$2]+=1}END{for(c in n)print c"\t"n[c]}' | grep -Fv = | tr -d \' | sort -k2,2nr
sed 406091
cat 173911
date 173029
[ 134083
tr 131509
cut 46355
pandoc 45615
rm 44974
set 44969
trap 44969
echo 44128
tee 43266
ls 43256
sort 6208
awk 5554
grep 5491
tac 5463
uniq 3109
head 3094
xargs 2397
nkf 2379
exit 857
read 23
cd 20
git 20
mv 20
xxd 10
cp 6
find 5
mkdir 5
tail 5
touch 5
true 4