Sat Apr 5 20:34:58 JST 2014 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 4280, keywords:コマンド,セルリアンタワー,シェルリアンタワー,CLI,Linux,Mac,USP友の会,勉強会,シェル芸,シェル芸勉強会 この記事は最終更新日が8年以上前のものです。
【本番資料】第10回シェル芸勉強会
他の回の問題はこちら
イントロ
環境
Linuxで解答を作ったのでMacな方は次のようにコマンドの読み替えを。
| Mac,BSD系 | Linux |
|---|---|
| gdate | date |
| gsed | sed |
| tail -r | tac |
| gtr | tr |
| gfold | fold |
Q1
次の数字の列を足し算してください。(できる人はなるべく変態的に)
$ echo 2 5 9 8 1 3 7 4
2 5 9 8 1 3 7 4A1
$ echo 2 5 9 8 1 3 7 4 | tr ' ' '+' | bc
39
$ echo 2 5 9 8 1 3 7 4 | awk '{for(i=1;i<=NF;i++){a+=$i}}END{print a}'
39
$ echo 2 5 9 8 1 3 7 4 | tr ' ' '\\n' | awk '{a+=$1}END{print a}'
39
###Tukubai###
$ echo 2 5 9 8 1 3 7 4 | ysum
2 5 9 8 1 3 7 4 39Q2
スペースと数字と改行を使って次のようなファイルを作り、書いた数を足し算してください。
$ cat nums
1
2 3
4 5
6 7
8 9A2
$ cat nums | tr ' ' '\\n' | awk 'NF==1' | awk '{a+=$1}END{print a}'
45
ueda@remote:~$ cat nums | xargs | tr ' ' '+' | bc
45
ueda@remote:~$ cat nums | xargs | ysum
1 2 3 4 5 6 7 8 9 45Q3
文字数を数えてください。改行記号は数えないでください。
ueda@remote:~$ cat genkou
筆者は朝、目玉焼きを食べた。
昼、著者は卵がけごはんを食べた。
そして夜、著者はマンハッタンの夜景を
見ながらゆで玉子を食べた。A3
(注意:ロケールで出力が違うことがあります。)
###これはNG###
ueda@remote:~$ wc -m genkou
65 genkou
ueda@remote:~$ cat genkou | tr -d '\\n' | wc -m
61
ueda@remote:~$ sed 's/./&\\n/g' genkou | awk 'NF==1' | wc -l
61
ueda@remote:~$ cat genkou | awk '{a+=length($1)}END{print a}'
61Q4
次のようなファイルを作り、ファイルの中に三個存在する文字を出力してください。
ueda@remote:~$ cat hoge
aabbcdabbcccddA4
ueda@remote:~$ cat hoge | sed 's/./&\\n/g' | awk 'NF==1' |
sort | uniq -c | awk '$1==3{print $2}'
a
d
ueda@remote:~$ cat hoge | sed 's/./&\\n/g' | sort |
awk 'NF==1' | count 1 1 | awk '$2==3{print $1}'
a
d
ueda@remote:~$ cat hoge | sed 's/./& /g' |
awk '{for(i=1;i<=NF;i++){x[$i]++};for(k in x){print k,x[k]}}' |
awk '$2==3{print $1}'
a
dQ5
次のようなファイル、ディレクトリを作ってください。そして、file1, file2, file3をカレントディレクトリに移動してください。
$ mkdir -p a/b/c
$ touch a/file1 a/b/file2 a/b/c/file3
$ tree
.
└── a
├── b
│ ├── c
│ │ └── file3
│ └── file2
└── file1
3 directories, 3 filesA5
$ find . -type f | while read f ; do mv $f ./ ; done
$ tree
.
├── a
│ └── b
│ └── c
├── file1
├── file2
└── file3
3 directories, 3 files
###別解###
$ find . -type f | xargs -I@ mv @ ./Q6
次のようにファイルとディレクトリを作り、hogeと書いてあるファイルをディレクトリa、 それ以外のファイルをディレクトリbに振り分けてください。
$ echo hoge > file1
$ echo huge > file2
$ echo hoge > file3
$ echo hoge > file4
$ mkdir a bA6
###2ライナーで###
$ ls file* | while read f ; do grep -q hoge $f && mv $f ./a ; done
$ ls file* | while read f ; do grep -qv hoge $f && mv $f ./b ; done
###エクストリームな方法###
$ ls file* | while read f ;¥
do grep -q hoge $f && mv $f ./a || mv $f ./b ; done
$ tree
.
├── a
│ ├── file1
│ ├── file3
│ └── file4
└── b
└── file2
2 directories, 4 files
$ for f in file* ; do grep -q hoge $f && mv $f ./a || mv $f ./b ; doneQ7
以下の9つのファイルについて、二つのファイルの組み合わせを全て列挙してください。ただし、重複してはいけません。
uedambp:~ ueda$ touch file{1..9}
uedambp:~ ueda$ ls file{1..9}
file1 file2 file3 file4 file5 file6 file7 file8 file9出力例
file1 file2
file1 file3
file1 file4
file1 file5
file1 file6
file1 file7
file1 file8
file1 file9
file2 file3 <- file2 file1 の組み合わせは既出なので出力しない
file2 file4
file2 file5
file2 file6
...A7
$ ls | while read f ; do echo $f file* ; done | awk '{for(i=2;i<=NF;i++){print $1,$i}}' | sort | awk '$1<$2'
###別解1###
$ echo file{1..9} | awk '{for(i=1;i<=9;i++){for(j=i+1;j<=9;j++){{print $i,$j}}}}'
###別解2###
ueda@remote:~$ echo file{1..9} | awk '{for(i=1;i<=9;i++){for(j=1;j<=9;j++){{print $i,$j}}}}' | awk '$1<$2'
###ツーライナーになるが・・・###
ueda@remote:~$ ls file{1..9} > hoge
ueda@remote:~$ loopx hoge hoge | awk '$1<$2'Q8
0から999999までの数字の一様乱数を無限に出力し続けてください。
A8
bash ueda@remote:~$ cat /dev/urandom | tr -dc '0-9' | fold -b6 | sed 's/^0*//' ###Macだとgtrとgfoldを使わないとコケる### uedambp:~ ueda$ cat /dev/urandom | gtr -dc '0-9' | gfold -b6 | sed 's/^0*//'
ノート
Tweet