【問題と解答】第27回sedこわいシェル芸勉強会
Sat Feb 11 16:13:15 JST 2017 (modified: Sat Sep 30 16:15:34 JST 2017)
views: 4055, keywords:コマンド,sed,勉強会,シェル芸,シェル芸勉強会 この記事は最終更新日が8年以上前のものです。
問題のみのページはこちら。
問題で使うファイル等
GitHubにあります。ファイルは
https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.27
にあります。
クローンは以下のようにお願いします。
$ git clone https://github.com/ryuichiueda/ShellGeiData.gitイントロ
環境
対象とするsedはGNU sedだけに絞っています。解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。
Q1
次のechoの出力について、偶数番目の文字だけ大文字にしてください。できたら、奇数番目の文字だけ大文字にしてください。
$ echo abcdefghijklmn解答
###偶数番目を大文字に###
$ echo abcdefghijklmn | sed 's/\\(.\\)\\(.\\)/\\1\\U\\2/g'
aBcDeFgHiJkLmN
###奇数番目を大文字に###
$ echo abcdefghijklmn | sed 's/\\(.\\)\\(.\\)/\\U\\1\\L\\2/g'
AbCdEfGhIjKlMn
###-rを使うと多少スッキリする###
$ echo abcdefghijklmn | sed -r 's/(.)(.)/\\U\\1\\L\\2/g'
AbCdEfGhIjKlMnQ2
seq 1 100から始めてsedだけでFizzBuzzをやってみましょう。
解答
$ seq 1 100 | sed '0~3s/.*/Fizz/;0~5s/$/Buzz/' |
sed 's/[0-9]*B/B/' | xargsQ3
次の出力について、3行目を7行目の下に移動してください。
$ seq 1 10解答
hで3行目をホールドスペースに突っ込み、Gでパターンスペースに戻します。
$ seq 1 10 | sed '3h;3d;7G'Q4
次のコードのmainとahoの位置を入れ替えてください。
$ cat aho.cc
#include <iostream>
using namespace std;
int main(int argc, char const* argv[])
{
aho();
return 0;
}
void aho(void)
{
cout << "aho" << endl;
}解答
mainの部分をホールドスペースに入れる→消す→ファイルの一番後ろでホールドスペースを吐き出すという流れになります。
$ cat aho.cc | sed '/int/,/}/H;/int/,/}/d;$G'
#include <iostream>
using namespace std;
void aho(void)
{
cout << "aho" << endl;
}
int main(int argc, char const* argv[])
{
aho();
return 0;
}
###{}でまとめる###
$ cat aho.cc | sed '/int/,/}/{H;d};$G'
###もうちょっと厳密なやつ###
$ cat aho.cc | sed '/ main(/,/^}/{H;d};$G'
###そのままコンパイルして実行###
$ cat aho.cc | sed '/int/,/}/H;/int/,/}/d;$G' |
g++ -x c++ - && ./a.out
ahoQ5
seq 1 10 | から始めて次のような出力を作ってください。
2
1
4
3
6
5
8
7
10
9解答
$ seq 1 10 | sed '1~2h;1~2d;0~2G'
2
1
4
3
6
5
8
7
10
9Q6
echo 1から始めて次のような出力を作ってください。
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111解答
ラベルを使います。
$ echo 1 | sed ':LOOP p;s/./&&/;b LOOP' | head
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111
###分岐を使う###
$ echo 1 | sed ':LOOP p;s/./&&/;/1\\{10\\}/!b LOOP'Q7
aというファイルをtouch等で作り、次の縛りでa1, a2, a3, ..., a10というファイルをaからコピーして作ってください。縛り1と縛り2を独立した別々の問題として解き、その後縛り1,2を両方満たす解を考えてみましょう。
- 縛り1: 使うコマンドはseq、cp、sedだけ
- 縛り2: ワンライナー中で数字を使わない
解答
###縛り1###
$ touch a
$ seq 1 10 | sed 's/./cp a a&/e'
$ ls a a? a10
a a1 a10 a2 a3 a4 a5 a6 a7 a8 a9
###縛り2###
$ yes | sed -n '=' | head | sed 's/./cp a a&/e'
###両方###
$ sed ':a ;p;s/./&&/;/........../!b a' <<< y |
sed -n = | sed 's/^/cp a a/e'
###(おまけ)ファイルaをsedで作る###
$ sed 'w a' <<< "abc"
abc
$ cat a
abcQ8
echo 1 | から始めて、あとはsedだけで次のような出力を得てください。
1
11
111
1111
11111
11111
1111
111
11
1解答
$ echo 1 | sed ':LOOP p;s/./&&/;/1\\{5\\}/!b LOOP' | sed 'p;1!G;h;$!d'
1
11
111
1111
11111
11111
1111
111
11
1
ノート
Tweet