<jupyter_start><jupyter_text>第2章: UNIXコマンド popular-names.txtは，アメリカで生まれた赤ちゃんの「名前」「性別」「人数」「年」をタブ区切り形式で格納したファイルである．以下の処理を行うプログラムを作成し，popular-names.txtを入力ファイルとして実行せよ．さらに，同様の処理をUNIXコマンドでも実行し，プログラムの実行結果を確認せよ  10. 行数のカウント行数をカウントせよ．確認にはwcコマンドを用いよ．<jupyter_code>with open('popular-names.txt', 'r', encoding='utf8') as f:
    print(len([1 for line in f]))
!wc -l popular-names.txt | awk '{print $1}'<jupyter_output>2780<jupyter_text>11. タブをスペースに置換タブ1文字につきスペース1文字に置換せよ．確認にはsedコマンド，trコマンド，もしくはexpandコマンドを用いよ．<jupyter_code>replaced_text = ''
with open('popular-names.txt', 'r', encoding='utf8') as f:
    replaced_text = f.read().replace('\t', ' ')

with open('output_py/q11.txt', 'w', encoding='utf8') as f:
    f.write(replaced_text)
!sed -e 's/\t/ /g' popular-names.txt > output/q11.txt<jupyter_output><empty_output><jupyter_text>12. 1列目をcol1.txtに，2列目をcol2.txtに保存各行の1列目だけを抜き出したものをcol1.txtに，2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ．確認にはcutコマンドを用いよ．<jupyter_code>col1 = []
col2 = []
with open('popular-names.txt', 'r', encoding='utf8') as f:
    splitted_lines = [line.split('\t') for line in f]
    for splitted_line in splitted_lines:
        col1.append(splitted_line[0])
        col2.append(splitted_line[1])

with open('output_py/q12_col1.txt', 'w', encoding='utf8') as f:
    f.write('\n'.join(col1))
with open('output_py/q12_col2.txt', 'w', encoding='utf8') as f:
    f.write('\n'.join(col2))
!cut -f 1 popular-names.txt > output/q12_col1.txt
!cut -f 2 popular-names.txt > output/q12_col2.txt<jupyter_output><empty_output><jupyter_text>13. col1.txtとcol2.txtをマージ12で作ったcol1.txtとcol2.txtを結合し，元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ．確認にはpasteコマンドを用いよ．<jupyter_code>with open('output_py/q12_col1.txt', 'r', encoding='utf8') as f:
    col1_lines = [line for line in f] # 各要素の末尾に改行文字を含む
with open('output_py/q12_col2.txt', 'r', encoding='utf8') as f:
    col2_lines = [line for line in f] # 各要素の末尾に改行文字を含む

merged_text_lines = [col1.rstrip('\n') + '\t' + col2 for col1, col2 in zip(col1_lines, col2_lines)]
with open('output_py/q13.txt', 'w', encoding='utf8') as f:
    f.writelines(merged_text_lines) # col2の改行文字だけ残し、writelinesで書き込み
!paste output/q12_col1.txt output/q12_col2.txt > output/q13.txt<jupyter_output><empty_output><jupyter_text>14. 先頭からN行を出力自然数Nをコマンドライン引数などの手段で受け取り，入力のうち先頭のN行だけを表示せよ．確認にはheadコマンドを用いよ．<jupyter_code>N = input('Input Natural number N -> ')
with open('popular-names.txt', 'r', encoding='utf-8') as f:
    N_lines = f.readlines()[:int(N):]
with open('output_py/q14.txt', 'w', encoding='utf8') as f:
    f.writelines(N_lines)
# コマンドライン引数の場合 ... 5 -> $1
!head -n 5 popular-names.txt > output/q14.txt<jupyter_output><empty_output><jupyter_text>15. 末尾のN行を出力自然数Nをコマンドライン引数などの手段で受け取り，入力のうち末尾のN行だけを表示せよ．確認にはtailコマンドを用いよ．<jupyter_code>N = input('Input Natural number N -> ')
with open('popular-names.txt', 'r', encoding='utf-8') as f:
    N_lines = f.readlines()
    N_lines = N_lines[len(N_lines)-int(N)::] # 末尾のN行を抽出
with open('output_py/q15.txt', 'w', encoding='utf8') as f:
    f.writelines(N_lines)
# コマンドライン引数の場合 ... 10 -> $1
!tail -n 10 popular-names.txt > output/q15.txt<jupyter_output><empty_output><jupyter_text>16. ファイルをN分割する自然数Nをコマンドライン引数などの手段で受け取り，入力のファイルを行単位でN分割せよ．同様の処理をsplitコマンドで実現せよ．<jupyter_code>N = input('Input Natural number N -> ')
with open('popular-names.txt', 'r', encoding='utf8') as f:
    all_lines = [line for line in f]

splitting_nums = len(all_lines) // int(N)
i = 0
while len(all_lines) - splitting_nums * i > 0:
    with open('output_py/q16_{}.txt'.format(i), 'w', encoding='utf8') as f:
        # 最後のループで、スライスの末尾の値が、元のリストの要素数を超える
        # -> 自動的に、len(all_lines) - 1まで収めてくれる
        f.writelines(all_lines[splitting_nums*i:splitting_nums*(i+1)])
    i += 1
# コマンドライン引数の場合 ... 3 -> $1
line_nums = !wc -l popular-names.txt | awk '{print $1}'
print("line_nums: {}".format(line_nums))
N = !expr {line_nums[0]} / 3
print("N: {}".format(N))
!split -l {N[0]} -d popular-names.txt output/q16.txt<jupyter_output>line_nums: ['2780']
N: ['926']<jupyter_text>17. １列目の文字列の異なり1列目の文字列の種類（異なる文字列の集合）を求めよ．確認にはcut, sort, uniqコマンドを用いよ．<jupyter_code>with open('popular-names.txt', 'r', encoding='utf8') as f:
    col1_texts = [line.split('\t')[0] for line in f]

with open('output_py/q17.txt', 'w', encoding='utf8') as f:
    # setで重複除去 -> sorted
    f.write('\n'.join(sorted(set(col1_texts))))
!cut -f 1 popular-names.txt | sort | uniq > output/q17.txt<jupyter_output><empty_output><jupyter_text>18. 各行を3コラム目の数値の降順にソート各行を3コラム目の数値の逆順で整列せよ（注意: 各行の内容は変更せずに並び替えよ）．確認にはsortコマンドを用いよ（この問題はコマンドで実行した時の結果と合わなくてもよい）．<jupyter_code>with open('popular-names.txt', 'r', encoding='utf8') as f:
    all_lines = [line for line in f]
sorted_lines = sorted(all_lines, key=lambda x: int(x.split('\t')[2]), reverse=True)

with open('output_py/q18.txt', 'w', encoding='utf8') as f:
    f.writelines(sorted_lines)
# Ubuntu(dash)以外では、"-t $'\t'"の書き方が使える
!sort -r -k 3 -t \t popular-names.txt > output/q18.txt<jupyter_output><empty_output><jupyter_text>19. 各行の1コラム目の文字列の出現頻度を求め，出現頻度の高い順に並べる各行の1列目の文字列の出現頻度を求め，その高い順に並べて表示せよ．確認にはcut, uniq, sortコマンドを用いよ．<jupyter_code>from collections import Counter

with open('popular-names.txt', 'r', encoding='utf8') as f:
    all_col1_texts = [line.split('\t')[0] for line in f]

counter = Counter(all_col1_texts)
frequency_col1_texts = ['{}\t{}\n'.format(num, word) for word, num in counter.most_common()]
with open('output_py/q19.txt', 'w', encoding='utf8') as f:
    f.writelines(frequency_col1_texts)
!cut -f 1 popular-names.txt | sort | uniq -c | sort -r -k 1 -t ' ' > output/q19.txt<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16621548456957227, 'fraction_numerical': 0.033567948023822416, 'mean_word_length': 5.875930521091812, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '27716', 'license': 'MIT', 'n_tokens_mistral': 2918, 'n_tokens_neox': 2910, 'n_words': 374, 'path': 'chapter2/chapter2.ipynb', 'repo_name': 'Mocchaso/NLP100knock_2020', 'size': '5541'}