Python subprocess パイプラインでsort, uniqコマンドに標準出力を渡したい


cat sample.txt | sort | uniq

サンプルファイル(sample.txt)

2021-04-05
2021-04-06
2021-04-05
2019-01-01

期待結果

$ cat sample.txt | sort | uniq
2019-01-01
2021-04-05
2021-04-06

サンプルコード

import subprocess as sb

args1 = ['cat', 'sample.txt']
args2 = ['sort']
args3 = ['uniq']

std = sb.PIPE

with sb.Popen(args=args1, stdout=std, stderr=std) as pr1:
    with sb.Popen(args=args2, stdin=pr1.stdout, stdout=std, stderr=std) as pr2:
        with sb.Popen(args=args3, stdin=pr2.stdout, stdout=std, stderr=std) as pr3:
            for date in pr3.stdout:
                print(date.decode('utf-8'))

実行結果

$ python3 subprocess_test.py


2019-01-01

2021-04-05

2021-04-06

cat sample.txt | sort | uniq | sort -k1,1 -k2,2n

サンプルファイル(sample.txt)

class2  80  +20
class1  64  +4
class4  55  -5
class3  67  +7
class2  79  +19
class3  48  -12
class4  55  -5
class1  64  +4

期待結果

$ cat sample.txt | sort | uniq | sort -k1,1 -k2,2n

class1  64      +4
class2  79      +19
class2  80      +20
class3  48      -12
class3  67      +7
class4  55      -5

サンプルコード

import subprocess as sb

args1 = ['cat', 'sample.txt']
args2 = ['sort']
args3 = ['uniq']
args4 = ['sort', '-k1,1', '-k3,3n']

std = sb.PIPE

with sb.Popen(args=args1, stdout=std, stderr=std) as pr1:
    with sb.Popen(args=args2, stdin=pr1.stdout, stdout=std, stderr=std) as pr2:
        with sb.Popen(args=args3, stdin=pr2.stdout, stdout=std, stderr=std) as pr3:
            with sb.Popen(args=args4, stdin=pr3.stdout, stdout=std, stderr=std) as pr4:
                for score in pr4.stdout:
                    print(score.decode('utf-8'))

実行結果

$ python3 subprocess_test.py


class1  64      +4

class2  79      +19

class2  80      +20

class3  48      -12

class3  67      +7

class4  55      -5

参考記事