第31回シェル芸勉強会解いたぞ

けんきうしつに配属されましたが、土曜出勤は今のところなさそうです。ということで、次回のシェル芸勉強会はぜひとも参加したい!!!

本日出題された問題を取り急ぎ解きました。相変わらずの awk 狂ですが、ご了承ください。
10/7 中に解くとか言いながら、日付をまたいでしまいました。しかも全部解き終わってないし。すみません。

なお、今回の勉強会はサークル内での総会があったため、そちらを優先。幹部だから当然ですよね!!

問題はこちら

第31回シェル芸勉強会解答

Q1

$ cat num.txt | sed 's/$/x/' | tr -d '\n' | sed 's/[0-9]\(x\?\)1/\11/g' | tr 'x' '\n'

とりあえず基本。正規表現ゲーですね。

Q2

$ cat indent.txt | awk -F\* '/^ /{a=$1;print} !/^ /{print a $0}'

インデント終わりの文字が * であることを悪用したシェル芸です。フィールドの区切り文字を * としました。

俺は生粋の Vimmer だ!!!という方はもちろん以下のような解き方も考えますよね。

$ vim -es indent.txt +'norm ggj==jj==jj==jj==' +'%p' +'q!'

Q3

$ seq -f " %2.f ********************" 20 | awk '{system(sprintf("factor %d | awk {printf\\ NF==2}", $1));print}' | awk '/^1/{print gensub(/\*/, "@", $2 ,$3);next} !/^1/&&$0=$3'

うん、もうやっつけだよね。

awk のスクリプトを整理したものをこちらに置いておきます。

{
    system(
        sprintf("factor %d | awk {printf\\ NF==2}", $1)
    );
    print
}
/^1/{
    print gensub(/\*/, "@", $2 ,$3);
    next
}
!/^1/&&$0=$3

Q4

$ curl -sL 'http://www.gojapango.com/japanese_language/japanese_words.htm' | grep gozaimasu | grep -o '^.........'

クックック…手段は問わないと言っただろう…?

Web ページのスクレイピングしただけです。しかも超原始的に。

Q6

まずは調査。「あいうえお」について。

$ echo あいうえお | xxd -c3 -u -ps
E38182
E38184
E38186
E38188
E3818A
0A

続いて「ぁぃぅぇぉ」について。

$ echo ぁぃぅぇぉ | xxd -c3 -u -ps
E38181
E38183
E38185
E38187
E38189
0A

0A は改行コード。それ以外の行を比べると、小さい文字のほうが対応する大きい文字に比べて数が1つだけ小さい。ということは…

$ echo あいうえお | xxd -c3 -u -ps | sed '$d;s/.*/&-1/;1iobase=16;ibase=16' | bc | xxd -p -r | awk 1

で出来た。

Q7

めっちゃ長いですが一応出来たので。

$ seq 3 | awk -v 'f=tput cup $(($(tput lines)-1)) $(($(tput cols)/2 + %d))' 'function a(n,s){system(sprintf(f, n));printf s} BEGIN{a(0,"^");print""} {system("sleep 1");a(-$1,"/");a($1,"\\");print""}'

貼り付けたあとですが、これはひどい…

awk 部分の整理:

function a(n,s){
    system(sprintf(f, n));
    printf s
}

BEGIN{
    a(0,"^");
    print""
} 

{
    system("sleep 1");
    a(-$1,"/");
    a($1,"\\");
    print""
}

Q8

$ cat sd.txt | tr -d '\n' | sed 's/./&\n/g' | awk '{d=/[\x20-\x7E]/?0.5:1.0;a+=d} {if(a>5){printf"\n"$0;a=d}else{printf$0}}'

いつもの awk 任せきました。[\x20-\x7E] は任意の半角文字を表す、そんな感じだった気がします(PC 内の実験ノートにそう書いてあった)。

awk 部分の整理:

{
    d = /[\x20-\x7E]/ ? 0.5 : 1.0;
    a+=d
}

{
    if(a > 5){
        printf "\n" $0;
        a=d
    }else{
        printf $0
    }
}

余談: チ○コチャレンジ

運試ししてみましたよ。

もう駄目だ。寝る。