LoginSignup
1
2

More than 5 years have passed since last update.

Gaucheで言語処理100本ノック2015 第2章: UNIXコマンドの基礎

Posted at

第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")))
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2