Help us understand the problem. What is going on with this article?

僕はプログラミングができません③ 〜言語処理100本ノック No.10-14〜

はじめに

言語処理100本ノック 2015という素敵教材をド素人が挑戦していく記事です。

前回まで

僕はプログラミングができません① 〜言語処理100本ノック No.01-04〜
僕はプログラミングができません② 〜言語処理100本ノック No.05-09〜

環境

Mac OS X 10.14.5
Python 3.7.1

準備

  • 「hightemp.txt」というテキストがサイトに用意してあるので、ローカルに配置します。

10. 行数のカウント

行数をカウントせよ.
確認にはwcコマンドを用いよ.

Pythonで実行

ファイルを読み込みラインの数だけカウントしてます。

import sys

fp = open(sys.argv[1], 'r')
i = 0
for line in fp.readlines():
    i += 1
fp.close()
print(i)

確認(Linuxコマンド)

$ wc -l hightemp.txt
24 hightemp.txt

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.
確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

Pythonで実行

import sys

fp = open(sys.argv[1], 'r')
for line in fp.readlines():
    print(line.expandtabs(1) ,end = '')
fp.close()

確認(Linuxコマンド)

Mac OSの場合タブ文字を扱うのに一工夫必要だったので以下のサイトを参考にしました。
BSD(Mac)のsedでのタブ文字を変換する3つの方法

ポイントとしては

  1. ¥\は区別される(Option + ¥\)
  2. \tprintfを使って出してあげること

2に関しては他にもやりかたありです。

# sed
# ¥tを (空白)で置き換える
$ sed "s/$(printf "\t")/ /g" hightemp.txt

# tr
# ¥tを (空白)で置き換える
$ cat hightemp.txt | tr '$(printf "\t")' ' '

# expand
# -t(tab)の文字をn文字(ここでは1文字)の空白に置き換える
$ expand -t 1 hightemp.txt

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.
確認にはcutコマンドを用いよ.

Pythonで実行

import sys

fp = open(sys.argv[1], 'r')
fnew1 = open ('col1.txt', 'w')
fnew2 = open ('col2.txt', 'w')
for line in fp.readlines():
    my_list = list()
    my_list = line.split()
    fnew1.write(my_list[0]+'\n')
    fnew2.write(my_list[1]+'\n')
fp.close()
fnew1.close()
fnew2.close()

確認(Linuxコマンド)

# 1列目をcol1_linux.txtに出力
$ cut -f 1 -d "$(printf "\t")" hightemp.txt > col1_linux.txt
# 2列目をcol2_linux.txtに出力
$ cut -f 2 -d "$(printf "\t")" hightemp.txt > col2_linux.txt
# Pythonで作成した文字列と比較
$ diff col1.txt col1_linux.txt
$ diff col2.txt col2_linux.txt

13. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.
確認にはpasteコマンドを用いよ.

import sys

# 12で作成したファイルを読み込む
with open('col1.txt') as f1:
    s1=f1.read()
with open('col2.txt') as f2:
    s2=f2.read()
# ファイルを改行で区切りリストにする
s1 = s1.split("\n")
s2 = s2.split("\n")

# リストから順番にファイルに出力する
i = 0
merge_file = open ('merge_file.txt', 'w')
for i in range(len(s1)-1):
    if i < len(s1)-2:
        merge_file.write(s1[i] + "\t" + s2[i] + "\n")
    else:
        merge_file.write(s1[i] + "\t" + s2[i])
merge_file.close()

確認(Linuxコマンド)

-dに指定している文字でcol1.txtとcol2.txtを結合する。

$ paste -d "$(printf "\t")" col1.txt col2.txt

14. 先頭からN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.
確認にはheadコマンドを用いよ.

import sys
line_num = 0
line_num = int(sys.argv[2])
i = 0
fp = open(sys.argv[1], 'r')
for line in fp.readlines():
    if i < line_num:
        print(line,end="")
        i += 1
    else:
        break
$ head -n 3 hightemp.txt

最後に

今回は結構時間かかりました。
Linuxは普段文字列操作系はあまり使わないので、色々調べて楽しかったのです。
なにかお気づきの点あればコメントいただけると幸いです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away