[PYTHON] How to write this process in Perl?

How to write this process in Python? is the second decoction.

Actually, practice while thinking about how to write if it is perl. Bind the CORE module as much as possible.

How to write this process in Perl?

Standard output / standard error output

#Message to standard output
echo 'HELLO'

#Message to standard error
echo 'ERROR!' >&2
use strict;
use warnings;

#Message to standard output
print "HELLO\n";
#Or v5.Say after using 10 or more
use v5.10;
say "HELLO";

#Message to standard error.(PBP p.235 γ€Œ10.12 Output to file handle)
print {*STDERR} "ERROR!\n";
#Or use warn. If there is no line break at the end, it will also tell you the position of the warning.
warn "ERROR!\n";

File related

Path operation

name="$(basename "/foo/bar/baz.txt")" # => baz.txt file name
name="$(dirname "/foo/bar/baz.txt")"  # => /foo/bar/Parent directory path
fullpath="/foo/bar/${name}"           # => /foo/bar/baz.txt Path concatenation
use strict;
use warnings;
use File::Basename qw(basename dirname);
use File::Spec;

my $name = basename("/foo/bar/baz.txt");  # => baz.txt
my $dir = dirname("/foo/bar/baz.txt");  # => /foo/bar
$fullpath = File::Spec->catfile("/foo/bar", $name);  # => /foo/bar/buz.txt

Handle paths containing tildes and environment variables

import pathlib

bad = pathlib.Path("~/Donwloads/report.txt") # ~Is not automatically deployed!

f = pathlib.Path("~/Donwloads/report.txt").expanduser()
g = pathlib.Path("${WORK_DIR}/input.txt").expandvars()
use strict;
use warnings;

my $bad = "~/Downloads/report.txt";

#Use glob. Watch out for wildcards.
my $f = glob '~/Downloads/report.txt';  #Access in scalar context.

# %You can take environment variables from ENV.
my $g = "$ENV{WORK_DIR}/input.txt";

Reading and writing files

import pathlib
path = pathlib.Path('foo.txt')

with open(path, 'r', encoding="utf-8") as f:
    for line in f:
        #Process line

with open(path, 'w', encoding="utf-8") as f:
    print("Contents", file=f)

with path.open('r') as f: #It can also be opened using the Path method.
    # ...
use strict;
use warnings;
use open qw/:encoding(UTF-8) :std/;
use utf8;
use autodie;

my $path = 'foo.txt';

READ: {
    open my $fh, '<', $path;

    while (<$fh>) {
        chomp(my $line = $_);
        # $Process line
    }

    close $fh;
}

WRITE: {
    open my $fh, '>', $path;
    print {$fh} "Contents";
    close $fh;
}

1;

Count the number of lines (wc -l)

with path.open('rb') as f:
    count = sum(1 for line in f)
use strict;
use warnings;
use autodie;
open my $fh, '<:raw', $path;
my $count = () = <$fh>;  #Take a file handle in a list context and access it in a scalar context.

File enumeration

import pathlib
dir = pathlib.Path('/tmp')
for file in dir.glob('tmp.*'):
    #Process the file
    #file is not a string, pathlib.Note that it is Path
use strict;
use warnings;

for my $file (glob '/tmp/tmp.*') {
    #Process the file
    # $file is a string
}

File information (existence confirmation / creation date and time)

import pathlib
f = pathlib.Path('/bin/bash')
f.exists()  #check existence

f.is_file() #File?
f.is_dir()  #directory?

f.stat().st_ctime #Creation date and time
f.stat().st_mtime #Update date and time
f.stat().st_atime #Access date and time
use strict;
use warnings;
use File::stat;

my $f = '/bin/bash';

my $sb = stat($f);  #Special file handle"_"Is cached.
-e _;  #check existence
-f _;  #File?
-d _;  #directory?

$sb->ctime;  #Creation date and time
$sb->mtime;  #Update date and time
$sb->atime;  #Access date and time

Move / Delete

import pathlib

path_from = pathlib.Path('.bash_history')
path_to = pathlib.Path('/tmp/.bash_history')
path_from.rename(path_to) #Move
path_from.unlink() #Delete
use strict;
use warnings;
use File::Copy qw(move);
use autodie qw(move);

my $path_from = '.bash_history';
my $path_to = '/tmp/.bash_history';
move $path_from, $path_to;  #Move
unlink $path_from;  #Delete

copy

import shutil
import pathlib

path_from = pathlib.Path('.bash_history')
path_to = pathlib.Path('/tmp/.bash_history')
shutil.copy2(path_from, path_to) #copy
use strict;
use warnings;
use File::Copy qw(copy);
use autodie qw(copy);

my $path_from = '.bash_history';
my $path_to = '/tmp/.bash_history';
copy $path_from, $path_to;

External command

Simply run

import subprocess
subprocess.run(['sl', '-h'], check=True)
use strict;
use warnings;
use autodie qw(system);
system qw(sl -h);

Execute an external command and receive standard output

import subprocess
r = subprocess.run(['echo', 'world'], check=True, stdout=subprocess.PIPE)
r.stdout # => b'\xe4\xb8\x96\xe7\x95\x8c\n' 'world\n'UTF-Encoded with 8
r.stdout.decode(sys.getfilesystemencoding()) # => 'world\n'
use strict;
use warnings;
use autodie;
use Encode;

#If the command to execute is safe
my $stdout = `echo world`;
$stdout;  # 'world\n'Binary string. No utf8 flag.
decode_utf8($stdout);  # 'world\n', With utf8 flag.

#If it's not safe
my @cmd = qw(echo world);
open my $fh, '-|', @cmd;
$stdout = do { local $/; <$fh> };  #Swallowing
close $fh;

#If you don't want to worry about the utf8 flag
{
    use utf8;
    use open qw/:encoding(UTF-8) :std/;
    open my $fh, '-|', @cmd;
    $stdout = do { local $/; <$fh> };  #with utf8 flag
    close $fh;
}

#Locale is UTF on older systems-Isn't it 8? are you serious? ??
{
    no utf8;
    use Encode::Locale;  # non-core
    my @lcmd = map { encode(locale => decode_utf8($_)) } @cmd;
    open my $fh, '-|', @lcmd;
    $stdout = decode(locale => do { local $/; <$fh> });
    close $fh;
}

Change environment variables and current directory

env = dict(os.environ) #Copy environment variables in Python script
env['DB_HOST'] = 'localhost' #Change environment variables

cwd = pathlib.Path('/')

subprocess.run(['setup.sh'], cwd=cwd, env=env)
use strict;
use warnings;
use Cwd qw(chdir);  #at chdir$ENV{PWD}Update
use autodie;

local $ENV{DB_HOST} = 'localhost';
my $orig_dir = Cwd::getcwd();

chdir "/";
system "setup.sh";
chdir $orig_dir;

Use redirects

import subprocess
import os.path

fi = open(os.path.expanduser('~/.bash_history'))
fo = open('p.txt', 'wb')
subprocess.run(['grep', 'python[23]'], stdin=fi, stdout=fo)
# p.Search results are output to txt
#CORE module binding
use strict;
use warnings;
use autodie;
use IPC::Open2;

open my $fh_history, '<', scalar glob '~/.bash_history';

my ($fh_out, $fh_in);
my $pid = open2($fh_out, $fh_in, 'grep', 'python');
print {$fh_in} $_ while <$fh_history>;
close $fh_in;
close $fh_history;

open my $fh_txt, '>:raw', 'p.txt';
print {$fh_txt} $_ while <$fh_out>;
close $fh_txt;
close $fh_out;

waitpid $pid, 0;
my $return_code = $? >> 8;

#If you can use other than the CORE module
use strict;
use warnings;
use IPC::Run3 qw(run3);  # non-core

my $fi = scalar glob '~/.bash_history';
my $fo = 'p.txt';

run3 ['grep', 'python[23]'], $fi, $fo;

Use a pipe

p1 = subprocess.Popen(["cat", '.bash_history'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "python"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
output = p2.communicate()[0] #From history'python'Results of searching for rows containing
p2.returncode #exit code of grep
use strict;
use warnings;
use autodie;
use IPC::Open2;

open my $fh_history, '<', scalar glob '~/.bash_history';

my ($fh_out, $fh_in);
my $pid = open2($fh_out, $fh_in, 'grep', 'python');

print {$fh_in} $_ while <$fh_history>;

close $fh_in;
close $fh_history;

waitpid $pid, 0;
my $returncode = $? >> 8;
my $output = do { local $/; <$fh_out> };

close $fh_out;

spawn β†’ wait (starts an external command and waits for the end)

import subprocess

p1 = subprocess.Popen(['/path/to/heavy-sub-process1'])
p2 = subprocess.Popen(['/path/to/heavy-sub-process2'])

p1.wait()
p2.wait()
use strict;
use warnings;

my @cmds = (
    ['/path/to/heavy-sub-process1'],
    ['/path/to/heavy-sub-process2'],
);

my @pids;
for my $cmd (@cmds) {
    my $pid = fork;
    if (!defined $pid) {
        die "Can't fork: $!";
    }
    elsif (!$pid) {
        exec @{$cmd};
        exit 1;
    }
    else {
        push @pids, $pid;
    }
}

my @rcs;
for my $pid (@pids) {
    waitpid $pid, 0;
    push @rcs, $? >> 8;
}

Run the shell

subprocess.run('echo Hello > /dev/null', shell=True)
system 'echo Hello > /dev/null';  #If there is a metacharacter, shell will be called

Time related

from datetime import datetime, timedelta #datetime represents the date and time, and timedelta represents the elapsed time

epoch = datetime.now().timestamp()
# => 1540277405.379158 Current Unix time (decimal)

datetime.fromtimestamp(1540277405).strftime('%FT%T')
# => '2018-10-23T15:50:05'

start = datetime.now()
#Do something that takes time

duration = datetime.now() - start # datetime -datetime is timedelta
print(duration / timedelta(seconds=1)) #To make the elapsed time numeric, divide by another timedelta
# => 42.680422 Seconds taken (decimal)
print(duration.total_seconds()) #This is OK
# => 42.680422 Seconds taken (decimal)
use strict;
use warnings;
use v5.12;
use Time::Piece;
use Time::HiRes;

my $epoch = localtime->epoch;
# =>Current Unix time (integer)

my $start = localtime;
#Do something that takes time

my $duration = localtime() - $start;  # Time::Piece - Time::Piece is Time::Seconds
say $duration->seconds;
# =>Number of seconds taken (integer)

my $frac_epoch = Time::HiRes::time();
# =>Current Unix time (decimal)

my $frac_duration = Time::HiRes::time() - $frac_epoch;
say $frac_duration;
# =>Number of seconds taken (decimal)

String relation

Embed expression in string

message='world!'
print(f"Hello {message}") # =>Hello world!
use strict;
use warnings;

my $message = 'world!';
print "Hello ${message}\n";  # =>Hello world!
print(f"1 + 2 = {1 + 2}") # => 1 + 2 = 3
use strict;
use warnings;

#Pass through the reference so that it can be embedded in the string
print "1 + 2 = ${\(1 + 2)}\n";  # => 1 + 2 = 3

Here document

import textwrap

report = textwrap.dedent(f"""
Report
date: {date}
""")
use strict;
use warnings;
use v5.26;
use Time::Piece;

my $report = <<~EOF;  #Relatively new perl indent
Report
date: ${\(localtime->strftime("%Y year%m month%d day"))}
    EOF

Command line arguments

import sys
sys.argv # => ['a.py', 'input.txt', '-o', 'output.txt']
#The program file name itself$It is in 0.
@ARGV; # => ('input.txt', '-o', 'output.txt')
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))
#!/usr/bin/perl
use v5.12;
use strict;
use warnings;
use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat permute);
use Pod::Usage qw(pod2usage);
use File::Basename qw(basename);
use List::Util qw(max sum);

#It may be a little awkward because I forcibly sent it to python's argparse.

my %args = (
    accumulate => \&max,
);

GetOptions(
    'h|help' => sub { pod2usage(0) },
    sum => sub { $args{accumulate} = \&sum },
) or pod2usage(1);

for my $arg (@ARGV) {
    if ($arg =~ /\D/) {
        pod2usage(
            -exitval => 1,
            -msg => "argument N: invalid int value: $arg",
        );
    }
}

say $args{accumulate}->(@ARGV);

1;
__END__

=pod

=encoding UTF-8

=head1 NAME

test.pl -- blah blah

=head1 SYNOPSIS

test.pl [-h] [--sum] N [N ...]

Process some integers.

=head2 OPTIONS

=over 2

=item C<-h>

show this help message

=item C<--sum>

sum the integers (default: find the max)

=back

=cut

Processing at the end & trapping the signal

import atexit
import os

tf = '/path/to/tempfile'

@atexit.register
def cleanup():
    os.remove(tf)
use strict;
use warnings;
use autodie;

my $tf = '/path/to/tmp';
$SIG{$_} = \&cleanup for qw( HUP INT QUIT TERM );

sub cleanup {
    unlink $tf;
}

HTTP request (alternative to curl or wget)

#Request URL with GET and output response body
import urllib.request
import urllib.parse

params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
url = f"http://www.musi-cal.com/cgi-bin/query?{params}"
with urllib.request.urlopen(url) as f:
     print(f.read().decode('utf-8'))
#Request URL with GET and output response body
use strict;
use warnings;
use v5.12;
use HTTP::Tiny;

my %params = (spam => 1, eggs => 2, bacon => 0);
my $url = 'http://www.musi-cal.com/cgi-bin/query';
my $response = HTTP::Tiny->new->get($url, \%params);
die "Failed" unless $response->{success};
say $response->{content};

Recommended Posts

How to write this process in Perl?
How to write soberly in pandas
How to write Ruby to_s in Python
How to write regular expression patterns in Linux
How to write async and await in Vue.js
How to write a named tuple document in 2020
How to write the correct shebang in Perl, Python and Ruby scripts
20th Offline Real-time How to Write Problems in Python
How to write string concatenation in multiple lines in Python
XPath Basics (2) -How to write XPath
How to develop in Python
How to write custom validations in the Django REST Framework
[Python] How to write an if statement in one sentence.
Summary of how to write .proto files used in gRPC
How to write a Python class
How to handle session in SQLAlchemy
How to use classes in Theano
How to collect images in Python
Flask reuse How to write html
How to update Spyder in Anaconda
How to use SQLite in Python
How to convert 0.5 to 1056964608 in one shot
How to reflect CSS in Django
How to kill processes in bulk
How to use Mysql in python
How to wrap C in Python
How to use ChemSpider in Python
How to use PubChem in Python
How to write Docker base image
How to write Django1.9 environment-independent wsgi.py
How to run TensorFlow 1.0 code in 2.0
Notes on how to write requirements.txt
How to handle Japanese in Python
How to log in to Docker + NGINX
How to call PyTorch in Julia
Repeated @ app.callback in Dash How to write Input and State neatly
The 15th offline real-time how to write reference problem in Python
How to use functions in separate files Perl and Python versions
How to use the asterisk (*) in Python. Maybe this is all? ..
How to write offline real time Solve E04 problems in Python
Difference in how to write if statement between ruby ​​and python
Difference in execution speed depending on how to write Cython function
The 18th offline real-time how to write reference problem in Python
How to use calculated columns in CASTable
[Introduction to Python] How to use class in Python?
How to suppress display error in matplotlib
Qiita (1) How to write a code name
How to dynamically define variables in Python
How to set optuna (how to write search space)
How to do R chartr () in Python
How to convert csv to tsv in CLI
How to write Python document comments (Docstrings)
How to delete expired sessions in Django
How to use Google Test in C
How to implement nested serializer in drf-flex-fields
How to work with BigQuery in Python
How to execute commands in jupyter notebook
How to do'git fetch --tags' in GitPython
How to get a stacktrace in python
How to display multiplication table in python
How to extract polygon area in Python