【問題と解答】第27回sedこわいシェル芸勉強会

Sat Feb 11 16:13:15 JST 2017 (modified: Sat Sep 30 16:15:34 JST 2017)
views: 3019, keywords:コマンド,sed,勉強会,シェル芸,シェル芸勉強会 この記事は最終更新日が7年以上前のものです。

問題のみのページはこちら。

問題で使うファイル等

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'
   AbCdEfGhIjKlMn

Q2

seq 1 100から始めてsedだけでFizzBuzzをやってみましょう。

解答

$ seq 1 100 | sed '0~3s/.*/Fizz/;0~5s/$/Buzz/' |
    sed 's/[0-9]*B/B/' | xargs

Q3

次の出力について、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
   aho

Q5

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
   9

Q6

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
   abc

Q8

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
ノート   このエントリーをはてなブックマークに追加 
 

prev:【問題のみ】第27回sedこわいシェル芸勉強会 next:jus共催第27回シェル芸勉強会のリンク集

やり散らかし一覧

記事いろいろ