シェル芸160本ノック解答例 その6
技術評論社から出版された『1日1問、半年以内に習得 シェル・ワンライナー160本ノック』の解答例です。
- 解答例の範囲: 問題51〜問題60
- 前回の解答例: シェル芸160本ノック解答例 その5
問題51
$ sed -E 's/^/00/;s/.*(... .*)/\1/' scores.txt | sort | join -a1 students.txt - | awk '{if(!$3)$3=0;print}'
001 井田 0
002 上田 40
003 江田 0
004 織田 0
005 加田 80
006 木田 95
007 久田 0
008 山田 76
問題52
$ awk '{if(/\*/){n=FILENAME;sub(/.*_/,"",n);for(i=1;i<NF;i++)c[i]=$(i+1)}else{for(i=1;i<NF;i++)printf "%s %s %s %d\n",n,$1,c[i],$(2+i-1)}}' data_{U,V}
U X A 4
U X B 2
U Y A 3
U Y B 1
V X A 7
V X B 6
V X C -1
V Y A 9
V Y B 8
V Y C -2
問題53
$ sort -k3,3 <(awk '{print $1,"@",$2}' devicelist.txt) <(awk '{print "@",$2,$1}' measurement.txt) | uniq -f2 --group | sed 's/^$/:/' | tr '\n' ' ' | tr : '\n' | awk '{if(NF==3){print $1,$3,$2}else{print $1,$3,$5}}' | sort
01 xxxx.0c4d.1c45 1914
02 xxxx.0d46.f3c2 @
03 xxxx.0d17.73a6 2275
04 xxxx.0d81.33b8 @
05 xxxx.0d17.9658 @
06 xxxx.0c4d.095c 3235
07 xxxx.0a69.b711 3119
08 xxxx.0d81.1da2 @
09 xxxx.0fff.d828 3618
10 xxxx.0d17.7478 3443
@ xxxx.0d81.33a8 1607
@ xxxx.17d0.2c07 3431
問題54
$ jq '.Fruits[]' fruits.json | tr '\n' @ | sed 's/}@/}\n/g' | awk '{match($3,/"(.+)",@/,n);gsub(/@/,"\n");print > n[1]".json"}'
このワンライナーを実行してfruits.json
から書き出したJSONファイルを確認します。
$ ls
Apple.json Banana.json Kiwifruit.json Mango.json Orange.json fruits.json
# 各JSONファイルの内容を出力
$ cat Apple.json
{
"Name": "Apple",
"Quantity": 3,
"Price": 100
}
$ cat Banana.json
{
"Name": "Banana",
"Quantity": 6,
"Price": 100
}
$ cat Kiwifruit.json
{
"Name": "Kiwifruit",
"Quantity": 40,
"Price": 50
}
$ cat Mango.json
{
"Name": "Mango",
"Quantity": 100,
"Price": 90
}
$ cat Orange.json
{
"Name": "Orange",
"Quantity": 15,
"Price": 110
}
問題55
# `sed -Ez ...`以降で中間ファイルを使った場合と同じ出力が得られるように整形
$ paste -d@ <(sed '$d' watch_log.json) <(sed '1d' watch_log.json) | sed 's/\\/\\\\/g' | while read l; do diff <(echo "$l" | awk -F@ '{print $1}' | jq . | sed 's/\\n/\n/g') <(echo "$l" | awk -F@ '{print $2}' | jq . | sed 's/\\n/\n/g'); done | sed -Ez 's/2c2\n< +("timestamp": )([^,]+),\n---\n> +\1([^,]+),/diff: \2 \3/g' | awk '{if(/^[0-9]+[acd][0-9]+$/){match($0,/([0-9]+)([acd])([0-9]+)/,m);printf "%d%s%d\n",m[1]-2,m[2],m[3]-2}else{print}}'
diff: "2020-01-18 18:06:52" "2020-01-18 18:07:06"
3c3
< drwxr-xr-x+ 86 uesugi staff 2752 1 18 18:06 ..
---
> drwxr-xr-x+ 86 uesugi staff 2752 1 18 18:07 ..
diff: "2020-01-18 18:07:06" "2020-01-18 18:07:20"
2c2
< drwxr-xr-x 19 uesugi staff 608 1 12 23:22 .
---
> drwxr-xr-x 20 uesugi staff 640 1 18 18:07 .
19a20
> -rw-r--r-- 1 uesugi staff 0 1 18 18:07 aaa
(...略...)
問題56
$ join -a1 <(awk -F '[:,] ' '{for(i=2;i<=NF;i++)printf "%s %s\n",$i,$1}' service_depend_list.txt | sort) <(awk -F '[:,] ' '{for(i=2;i<=NF;i++)printf "%s %s\n",$1,$i}' service_stop_weekday.txt | sort) | awk '{print $3,$2}' | sed 'y/日月火水木金土/0123456/' | sort -u | awk '{a[$1]=a[$1] ", "$2}END{for(w in a)print w,a[w]}' | sed 'y/0123456/日月火水木金土/;s/ , /: /'
日: アプリB, アプリE
月: アプリA, アプリC, アプリD
火: アプリB, アプリC, アプリE
水: アプリB, アプリC, アプリE
木: アプリA
金: アプリC, アプリD
土: アプリA, アプリB, アプリC, アプリD, アプリE
問題57
$ pandoc -t gfm table.md | sed -E 's/ ?\| ?/|/g;1h;2x;2s/[^| ]/-/g'
|AAA |BBB|CCC|
|--- |---|---|
|1 |123|4 |
|10000|1 |64 |
|3 |3 |3 |
問題58
$ sed 's/"[^"]\+"/\n&\n/g' num.csv | sed '/^"/s/[",]//g;s/,/ /g' | xargs | tr ' ' + | bc
1235362.19999999999999999999999
問題59
$ pandoc -f csv -t plain data.csv | sed '2d' | awk '{print NR,NF}' | sort -k2,2n | uniq -uf1 | sed 's/ .*//'
4
問題60
$ dateutils.dseq -f '%F-%a' 2017-02-24 2017-12-31 | awk -F- '/Fri/{d[$1"-"$2]=$3}END{for(Ym in d)print Ym"-"d[Ym]}' | sort
2017-02-24
2017-03-31
2017-04-28
2017-05-26
2017-06-30
2017-07-28
2017-08-25
2017-09-29
2017-10-27
2017-11-24
2017-12-29
# `dateutils.dround`を利用した別解
$ echo 2017-{03..12}-01 2018-01-01 | tr ' ' '\n' | dateutils.dround -n -- -Fri
2017-02-24
2017-03-31
2017-04-28
2017-05-26
2017-06-30
2017-07-28
2017-08-25
2017-09-29
2017-10-27
2017-11-24
2017-12-29
Written on October 26, 2022