第2章: UNIXコマンドの基礎
hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.
10. 行数のカウント
行数をカウントせよ.確認にはwcコマンドを用いよ.
(use file.util)
(print (length (file->string-list "hightemp.txt")))
11. タブをスペースに置換
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
(use file.util)
(use srfi-13)
(print (string-map (lambda (x) (if (eqv? x #\tab) #\space x))
(file->string "hightemp.txt")))
12. 1列目をcol1.txtに,2列目をcol2.txtに保存
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
(use file.util)
(let* ((rows (map (lambda (x) (string-split x #\tab))
(file->string-list "hightemp.txt")))
(col1 (map car rows))
(col2 (map cadr rows)))
(call-with-output-file "col1.txt"
(lambda (p) (display (string-join col1 "\n") p)))
(call-with-output-file "col2.txt"
(lambda (p) (display (string-join col2 "\n") p))))
13. col1.txtとcol2.txtをマージ
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
(use file.util)
(use srfi-1)
(let ((col1 (file->string-list "col1.txt"))
(col2 (file->string-list "col2.txt")))
(print (string-join (map (lambda (x) (string-join x "\t"))
(zip col1 col2))
"\n")))
14. 先頭からN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.
(use file.util)
(let ((n (string->number (car *argv*))))
(print (string-join (take (file->string-list "hightemp.txt") n)
"\n")))
15. 末尾のN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
(use file.util)
(let ((n (string->number (car *argv*))))
(print (string-join (take-right (file->string-list "hightemp.txt") n)
"\n")))
16. ファイルをN分割する
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.
(use file.util)
(use gauche.sequence)
(let* ((n (string->number (car *argv*)))
(ls (file->string-list "hightemp.txt"))
(m (if (eq? (remainder (length ls) n) 0)
(quotient (length ls) n)
(+ (quotient (length ls) n) 1))))
(for-each-with-index
(lambda (i x)
(call-with-output-file
(string-append (number->string i) ".txt")
(lambda (p) (display (string-join x "\n") p))))
(slices ls m)))
17. 1列目の文字列の異なり
1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.
(use file.util)
(let* ((rows (map (lambda (x) (string-split x #\tab))
(file->string-list "hightemp.txt")))
(col1 (map car rows)))
(print (string-join (delete-duplicates col1) "\n")))
18. 各行を3コラム目の数値の降順にソート
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).
(use file.util)
(let* ((xs (file->string-list "hightemp.txt"))
(ys (sort xs
<
(lambda (x) (string->number
(caddr
(string-split x #\tab)))))))
(print (string-join ys "\n")))
19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
(use file.util)
(let* ((xs (file->string-list "hightemp.txt"))
(ys (make-hash-table 'string=?))
(zs
(begin
(for-each (lambda (x)
(hash-table-push! ys
(car (string-split x #\tab))
x))
xs)
(fold append '()
(sort (hash-table-values ys)
<
(lambda (z) (length z)))))))
(print (string-join zs "\n")))