Package: pypipe-ppp
pypipe$echo"pypipe"|ppp"line[::2]"ppppypipeis a Python command-line tool for pipeline processing.DemoQuick linksInstallationBasic usage and ExamplesAutomatic Import and Explicit ImportAutomatic type conversion-t, --convertView mode-v, --viewOutput formattingCounter-c, --counterpypipe is a code generator.PagerInstallationpypipe is a single Python file and uses only the standard library. You can use it by placingpypipe.pyin a directory included in your PATH (e.g., ~/.local/bin). If execute permission is not already present, please add it.chmod+xpypipe.pyTo make it easier to type, it's recommended to create a symbolic link.ln-spypipe.pyppp[!Note]
pypipe requires Python 3.6 or later.pypipe can also be installed in the standard way for Python packages, usingpipor any compatible tool such aspipx.pipxinstallpypipe-pppIt also supports running directly with pipx without installation.pipxrunpypipe-ppp<args>You can also use it withWasmer:aliasppp="wasmer run bugen/pypipe -- "Basic usage and Examples| ppp lineProcessing line by line. You can get the line string aslineorland the line number asi.$catstaff.txt|ppp'i, line.upper()'1NAMEWEIGHTBIRTHAGESPECIESCLASS2SIMBA2501994-06-1529LIONMAMMAL3DUMBO40001941-10-2381ELEPHANTMAMMAL4GEORGE201939-01-0184MONKEYMAMMAL5POOH11921-08-21102TEDDYBEARARTIFACT6BOB01999-05-0124SPONGEDEMOSPONGEUsing the-j, --jsonoption allows you to decode each line as JSON. The decoded result can be obtained as a dictionarydic.$catstaff.jsonlines.txt|ppp-j'dic["Name"]'Simba
Dumbo
George
Pooh
Bob| ppp recSplit each line by TAB. You can get the list including splitted strings asrecorrand the record number asi..catstaff.txt|ppprec'r[:3]'NameWeightBirth
Simba2501994-06-15
Dumbo40001941-10-23
George201939-01-01
Pooh11921-08-21
Bob01999-05-01Using the-l LENGTH, --length LENGTHoption allows you to get the values of each field asf1, f2, f3, ....$tail-n+2staff.txt|ppprec-l5'f"{f1} is {f4} years old"'Simbais29yearsold
Dumbois81yearsold
Georgeis84yearsold
Poohis102yearsold
Bobis24yearsold[!Tip]
You can now use field variables (f1, f2, f3, ...) without specifying the--lengthoption.$ cat staff.txt | ppp rec f1,f2,f3Using field variables can make typing easier, but you have to know the number of fields in advance. Omitting the--lengthoption makes it more convenient to use, but if you omit it, performance will be degraded. In tests, processing data with about 60,000 records and 23 items took 0.45 seconds when specifying the--lengthoption, whereas omitting the--lengthoption took about 0.75 seconds. To maintain performance, either use the--lengthoption or retrieve fields from rec using indices likerec[0], rec[1], rec[2], ...without using field variables.When using the-H, --headeroption, it treats the first line as a header line and skips it. The header values can be obtained from a list namedheader, and you can access the values of each field using the formatdic["FIELD_NAME"].$catstaff.txt|ppprec-H'rec[0], dic["Birth"]'Simba1994-06-15
Dumbo1941-10-23
George1939-01-01
Pooh1921-08-21
Bob1999-05-01By using the--type FIELD_TYPES, --field-type FIELD_TYPES, you can specify the type of each field, allowing you to convert values from 'str' to the specified type.$echo'Hello	100	10.2	True	{"id":100,"title":"sample"}'|ppprec-l5--type2:i,3:f,4:b,5:j"type(f1),type(f2),type(f3),type(f4),type(f5)"<class'str'><class'int'><class'float'><class'bool'><class'dict'>[!Tip]
When there is a header row in the data, using--type, --field-typeoften results in errors when attempting to convert the header row's item names to the specified types. In such cases, you can avoid errors by using the-H, --headeroption to skip the header row.[!Note]
pypipe has added support forautomatic type conversion.You can change the delimiter by using the-d DELIMITER, --delimiter DELIMITERoption.$catstaff.csv|ppprec-d,-l6f1
Name
Simba
Dumbo
George
Pooh
BobAlso supports regular expression delimiters.$echo'AAA      BBB CCC    DDD'|ppprec-d'\s+'rec[2]CCC[!Tip]-S, --spacesoption has the same meaning as-d '\s+'.You can change the output delimiter by using the-D DELIMITER, --output-delimiter DELIMITERoption.$catstaff.txt|ppprec-D,
Name,Weight,Birth,Age,Species,Class
Simba,250,1994-06-15,29,Lion,Mammal
Dumbo,4000,1941-10-23,81,Elephant,Mammal
George,20,1939-01-01,84,Monkey,Mammal
Pooh,1,1921-08-21,102,Teddybear,Artifact
Bob,0,1999-05-01,24,Sponge,DemospongeWhen using the-m, --regex-matchoption,recis generated through regular expression matching instead of delimiter-based splitting.$echo'Height: 200px, Width: 1000px'|ppprec-m'\d+'r[1]1000| ppp csvcsvis similar torec, but the difference is that whilerecsimply splits the line using the specified DELIMITER like this,'line.split(DELIMITER))',csvuses thecsvlibrary for parsing. Furthermore,recis tab-separated by default, whereascsvis comma-separated.You can specify options to pass to csv.reader and csv.writer using the-O NAME=VALUE, --csv-opt NAME=VALUEoption.$catstaff.csv|pppcsv-O'quoting=csv.QUOTE_ALL'"Name","Weight","Birth","Age","Species","Class""Simba","250","1994-06-15","29","Lion","Mammal""Dumbo","4000","1941-10-23","81","Elephant","Mammal""George","20","1939-01-01","84","Monkey","Mammal""Pooh","1","1921-08-21","102","Teddy bear","Artifact""Bob","0","1999-05-01","24","Sponge","Demosponge"| ppp textInppp text, the entire standard input is read as a single piece of text. You can access the read text astext.$catstaff.txt|ppptext'len(text)'231For example,ppp textis particularly useful when working with an indented JSON file. Using the-j, --jsonoption allows you to decode the text into JSON. The decoded data can be obtained as adic.$catstaff.json|ppptext-j'dic["data"][0]'{'Name':'Simba','Weight':250,'Birth':'1994-06-15','Age':29,'Species':'Lion','Class':'Mammal'}[!Tip]
You can also use-j, --jsonoption inlineandfile.| ppp fileInppp file, it receives a list of file paths from standard input. It then opens each received file path, reads the contents of the file intotext, and repeats this process for each received file path in a loop. The received paths can be obtained aspath.$lsstaff.txtstaff.csvstaff.jsonstaff.xml|pppfile'path, len(text)'staff.csv231staff.json1046staff.txt231staff.xml1042For example,ppp fileis useful, especially when processing a large number of JSON files.find.-name'*.json'|pppfile--json...| ppp custom -N NAMEYou can easily create custom commands using pypipe. First, you define custom commands. The definition file is, by default, located at~/.config/pypipe/pypipe_custom.py. You can change the path of this file using thePYPIPE_CUSTOMenvironment variable.The following is an example of defining custom commands xpath and sum.~/.config/pypipe/pypipe_custom.pyTEMPLATE_XPATH=r"""from lxml import etree{imp}def output(e):if isinstance(e, etree._Element):print(etree.tostring(e).decode().rstrip())else:_print(e){pre}tree = etree.parse(sys.stdin)for e in tree.xpath('{path}'):{loop_head}{loop_filter}{main}{post}"""TEMPLATE_SUM=r"""import reimport sys{imp}ptn = re.compile(r'{pattern}')s = 0def add_or_print(*args):global srec = args[0]if len(args) == 2:if isinstance(args[1], int):i = args[1]if len(rec) >= i:s += rec[i-1]else:print(args[1])else:print(*args[1:])for line in sys.stdin:line = line.rstrip('\r\n')rec = [{type}(e) for e in ptn.findall(line)]if not rec:continue{loop_head}{loop_filter}{main}print(s)"""custom_command={"xpath":{"template":TEMPLATE_XPATH,"code_indent":1,"default_code":"e","wrapper":'output({})',"options":{"path":{"default":'/'}}},"sum":{"template":TEMPLATE_SUM,"code_indent":1,"default_code":"1","wrapper":'add_or_print(rec,{})',"options":{"pattern":{"default":r'\d+'},"type":{"default":'int'}}},}You can use them as follows:$catstaff.xml|pppcustom-Nxpath-Opath='./Animal/Age'<Age>29</Age>
<Age>81</Age>
<Age>84</Age>
<Age>102</Age>
<Age>24</Age>$seq10000|pppc-Nsum-f'rec[0] % 3 == 0'16668333Automatic Import and Explicit Importpypipe attempts to automatically import the necessary modules. While explicit import is likely not required in most cases, it is also possible to explicitly import the necessary modules using the-i IMPORT, --import IMPORToption. The following examples all work in the same way:$seq10|ppp'math.sqrt(int(line))'$seq10|ppp-imath'math.sqrt(int(line))'$seq10|ppp-i'from math import sqrt''sqrt(int(line))'Using the explicit import formatfrom <module> import <function>can be useful in cases where you need to use the<function>multiple times within the code.[!Note]
See alsohereabout-i IMPORT, --import IMPORToption.Automatic type conversion-t, --convertWhen using the -t, --convert option, it automatically converts the input types.$echo'Hello	100	10.2	True	None	(1,2,3)	[1,2,3]	{1,2,3}	{"id":100,"title":"sample"}'|ppprec--view-t"[(v, type(v)) for v in rec]"[Record 1]1  ('Hello', <class 'str'>)2  (100, <class 'int'>)3  (10.2, <class 'float'>)4  (True, <class 'bool'>)5  (None, <class 'NoneType'>)6  ((1, 2, 3), <class 'tuple'>)7  ([1, 2, 3], <class 'list'>)8  ({1, 2, 3}, <class 'set'>)9  ({'id': 100, 'title': 'sample'}, <class 'dict'>)In the following example, there is no longer a need to explicitly convert to a numeric type likeint(rec[1]) > 100; it now works withrec[1] > 100.$catstaff.txt|ppprec--convert--header--filter'rec[1] > 100'Simba   250     1994-06-15      29      Lion    MammalDumbo   4000    1941-10-23      81      Elephant        Mammal[!Tip]
The-t, --convertoption is available for use with line, rec, csv, text, and file.[!Tip]
Automatic type conversion supports int, float, bool, None, json (dict, list, bool, null), and eval (tuple, list, set, dict).[!Warning]
The-t, --convertoption is convenient but may lead to a performance degradation when used. It should not be used if performance is crucial.View mode-v, --viewWhen using the-v, --viewoption, the output is pretty printed with colored formatting. Data formats with many items such as CSV, TSV, JSON, and others can be hard to read in their raw format, making the View mode particularly useful when inspecting such data. In View mode,dict,listandtupleare formatted using the standard library'spprint.When you use both the-v, --viewoption and the-H, --headeroption together, it displays the values along with the field names.In View mode,dict,listandtupleare formatted using the standard library'spprint.-k COLOR_MODE, --color COLOR_MODEIn View mode, pypipe automatically determines whether to apply colorization. By default, when outputting to a terminal, the output will be in color. However, if you redirect the output to a file or pipe it to another command, it will not be in color. You can change this behavior using the-k COLOR_MODE, --color COLOR_MODEoptions:Using-k autoor--color autolets the tool automatically decide whether to apply colorization.Using-k alwaysor--color alwaysforces colorization at all times.Using-k neveror--color neverdisables colorization.Also, by setting thePYPIPE_VIEW_COLOREDenvironment variable tofalse, you can disable colors by default. However, if the-k, --coloroption is specified, it takes precedence.Output formattingIn pypipe, you have the flexibility to write code to output results in any desired format. For example:$echo"Hello"|pppline-n'print(line + " World!")'HelloWorld!Please note the presence of the-noption in the command above. If you omit this option, the output will look like this:$echo"Hello"|pppline'print(line + " World!")'HelloWorld!
NoneSo, what's happening here? When you have questions about pypipe's behavior, a good approach is to inspect the code generated using the-p, --printoption.~$echo"Hello"|pppline'print(line + " World!")'-p# IMPORTimportsys
fromfunctoolsimportpartial# PRE_p=partial(print,sep="\t")# ABBREVI,S,B,L,D,SET=0,"",False,[],{},set()# ABBREVdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))fori,lineinenumerate(sys.stdin,1):line=line.rstrip("\r\n")l=line# ABBREV# LOOP HEAD# LOOP FILTER# MAIN_print(print(line+" World!"))# POSTIn this case, runningppp line 'print(line + " World!")' -pshould reveal a line in the generated code like_print(print(line + " World!")). This is due to a unique feature of pypipe called asCode wrapping.Let's make a slight modification to the command by removing the print function:$echo"Hello"|pppline'line + " World!"'HelloWorld!Indeed, pypipe is designed to allow the omission of the print function for less typing.Change the behavior of the_printfunctionBy default, the_print({})wrapper is used. The_printfunction is an internally implemented output function in pypipe and has the following implementation:def_print(*args,sep='\t'):iflen(args)is1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))You can replace the implementation of the _print function using the-F FORMAT, --output-format FORMAToption. pypipe allows you to control the output format by changing the implementation of the _print function.-Fd, -F default, --output-format=defaultDefault output format.Implementation of the _print function: as described above.Output example:$echo'["aaa", "bbb", "ccc"]'|ppp--json-Fddic
aaabbbccc-Fj, -F json, --output-format=jsonConvertsdict,list, andtupleto JSON format for output. However, when a single string is passed, it will not be enclosed in double quotes (meaning it is not in JSON string format).Implementation of the_printfunction:def_json(v):ifisinstance(v,(dict,list,tuple)):v=json.dumps(v)elifnotisinstance(v,str):v=str(v)returnvdef_print(*args,sep='\t'):print(sep.join(_json(v)forvinargs))Output example:$echo'["aaa", "bbb", "ccc"]'|ppp--json-Fjdic["aaa","bbb","ccc"]-Fn, -F native, --output-format=nativeUses the standard print function for output.Implementation of the_printfunction:_print=partial(print,sep='\t')Output example:$echo'["aaa", "bbb", "ccc"]'|ppp--json-Fndic['aaa','bbb','ccc']Change the output delimiter-D DELIMITER, --output-delimiter DELIMITERYou can change the output delimiter using the-D DELIMITER, --output-delimiter DELIMITERoption. The delimiter does not have to be a single character, you can specify multiple characters [^1].$catstaff.txt|ppprec-D' | 'Name|Weight|Birth|Age|Species|Class
Simba|250|1994-06-15|29|Lion|Mammal
Dumbo|4000|1941-10-23|81|Elephant|Mammal
George|20|1939-01-01|84|Monkey|Mammal
Pooh|1|1921-08-21|102|Teddybear|Artifact
Bob|0|1999-05-01|24|Sponge|Demosponge[^1]: Internally, the character specified using the-D, --output-delimiteroption is passed as thesepargument to the_printfunction. Then, you can specify multiple characters forsep. However, it's important to note that in thecsvcommand, a different output function usingcsv.writeris used as a wrapper, rather than the_printfunction. In this case, the character specified using the-D, --output-delimiteroption is passed as thedelimiterargument tocsv.writer, and specifying multiple characters for the delimiter is not possible.-L, --linebreakThe-L, --linebreakoption has the same meaning as-D '\n', --output-delimiter '\n'. It is useful when connecting pypipe's output to pypipe. Instead of writing a for loop in pypipe, you can use-L, --linebreakto connect to the next pypipe, enabling you to achieve similar processing as nested for loops.Using-Lto output with line breaks:$catstaff.json|ppptext-j'*dic["data"]'-Fj-L{"Name":"Simba","Weight":250,"Birth":"1994-06-15","Age":29,"Species":"Lion","Class":"Mammal"}{"Name":"Dumbo","Weight":4000,"Birth":"1941-10-23","Age":81,"Species":"Elephant","Class":"Mammal"}{"Name":"George","Weight":20,"Birth":"1939-01-01","Age":84,"Species":"Monkey","Class":"Mammal"}{"Name":"Pooh","Weight":1,"Birth":"1921-08-21","Age":102,"Species":"Teddy bear","Class":"Artifact"}{"Name":"Bob","Weight":0,"Birth":"1999-05-01","Age":24,"Species":"Sponge","Class":"Demosponge"}To further process this output:$catstaff.json|ppptext-j'*dic["data"]'-Fj-L|ppp-j'dic["Weight"]'|pppc-Nsum4271This can also be written as follows. Please use your preferred method:$catstaff.json|ppptext-j'> for r in dic["data"]:>     I += r["Weight"]> '-n-a'print(I)'4271Counter-c, --counterUsing the-c, --counteroption allows for easy data aggregation. When you specify the-c, --counteroption, it creates an instance of collections.Counter, which can be accessed as eithercounterorc. The-c, --counteroption is available for use in all commands.An example of aggregating data by the 'Gender' and 'Hobby' fields.$catpeople.csv|pppcsv-H--counter'dic["Gender"], dic["Hobby"]'|head-n10
FemaleCooking4MaleHiking3FemaleReading3MaleGardening3FemaleTraveling3MalePlayingMusic3FemaleDancing3FemaleHiking3FemalePainting2MalePhotography2This is an example to aggregate data based on whether female individuals are 30 years or older.catpeople.csv|pppcsv-H-c-f'dic["Gender"] == "Female"''int(dic["Age"]) >= 30'False16True10When using the-c, --counteroption, it usescounter[{}] += 1as the wrapper. If you want to count in a different way, you can disable the wrapping by using the-n, --no-wrappingoption and add your own counting code.$catpopulation.csv|pppcsv-H-c-n'counter[dic["State"]] += int(dic["Population"])'NewYork8398748Texas7751480California7327731Illinois2705994Arizona1680992Pennsylvania1584138Florida903889Ohio892533Indiana876862NorthCarolina792862Washington753675Michigan673104Information aboutCode wrapping.pypipe is a code generator.pypipe is a command-line tool for pipeline processing, but it can also be thought of as a code generator. It generates code internally using the given arguments and then executes the generated code using theexecfunction. Therefore, instead of executing the generated code, you have the option to print it to the standard output or save it to a file.Print generated code.-p, --printTo check the generated code, you can use the-p, --printoption.pppfile-mrb-ihashlib-b'total = 0'-b'_p("PATH", "SIZE", "MD5")'-e'size = len(text)'-f'path.stem == "staff"''total += size''path, size, hashlib.md5(text).hexdigest()'-a'print(f"Total size: {total}")'-pThe generated code is output as follows.# IMPORTimportsysfromfunctoolsimportpartialimportgzipfrompathlibimportPathimporthashlibdef_open(path):ifpath.suffix=='.gz':returngzip.open(path,'rb')else:returnopen(path,'rb')# PRE_p=partial(print,sep="\t")# ABBREVI,S,B,L,D,SET=0,"",False,[],{},set()# ABBREVdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))total=0_p("PATH","SIZE","MD5")fori,lineinenumerate(sys.stdin,1):path=Path(line.rstrip('\r\n'))with_open(path)asfile:text=file.read()# LOOP HEADsize=len(text)# LOOP FILTERifnot(path.stem=="staff"):continue# MAINtotal+=size_print(path,size,hashlib.md5(text).hexdigest())# POSTprint(f"Total size:{total}",file=sys.stderr)Check that there are no issues with the generated code and execute it.$finddocs-typef|pppfile-mrb-ihashlib-b'total = 0'-b'_p("PATH", "SIZE", "MD5")'-e'size = len(text)'-f'path.stem == "staff"''total += size''path, size, hashlib.md5(text).hexdigest()'-a'print(f"Total size: {total}")'PATHSIZEMD5
docs/staff.json10463f81986424eea2648bcabec324f8e959
docs/staff.txt231a0757fb3838ed1235b21f96e1953445c
docs/staff.xml10427d36d493c1dd7594db3426f242b667f6
docs/staff.csv2316cba6414c49b8762d6a49e2d9a62e563
Totalsize:2550Save generated code to a file.-o PATH, --output PATHFor writing more complex code, it's a good practice to create a template code with pypipe and edit the templated code manually. Here's the process you can follow:Create a template code with pypipe and save it to a file, for example:pppline--output/tmp/pipe.py...Edit the code in /tmp/pipe.py to suit your needs.Execute the modified code by piping input to it, for example:catsample.txt|/tmp/pipe.pyMain codesThe main code is specified as positional arguments. You can specify multiple main codes. The placement of the main code varies depending on the command. In commands likeline,rec,csv, andfile, the main code is added within the loop processing with proper indentation. However, in thetextcommand, where there is no loop processing, the main code is added without indentation.
In thecustomcommand, the main code is added according to the definitions provided in thepypipe_custom.pyfile.$ppptext-pqrn"for word in text.split():""    print(word)"importsysfromfunctoolsimportpartialdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))text=sys.stdin.read()forwordintext.split():# <- HEREprint(word)# <- HEREYou can also write it with line breaks in the terminal as follows:$ppptext-pqrn'> for word in text.split():>     print(word)> 'Default main codeIf no main code is specified in the arguments, pypipe adds a predefined default code. For example, the default code in Line mode is'line'.ppp-pqrimportsysfromfunctoolsimportpartialdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))fori,lineinenumerate(sys.stdin,1):line=line.rstrip("\r\n")_print(line)# Default code with code wrappping.Code wrappingBy default, pypipe wraps the last code specified in the arguments with a predefined wrapper. For example, inppp line, it uses'_print({})'as the wrapper. However, if the-c, --counteroption is specified, it uses'counter[{}] += 1'as the wrapper instead.$pppline'year = int(line)'year-pqrimportsysfromfunctoolsimportpartialdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))fori,lineinenumerate(sys.stdin,1):line=line.rstrip("\r\n")year=int(line)_print(year)# WrappingDisable code wrapping.-n, --no-wrappingIf you want to disable the wrapping of the last code specified in the arguments by a predefined wrapper, you can use the-n, --no-wrappingoption.$pppline-n'I = max(len(line), I)'-a'print(I)'-pqimportsysfromfunctoolsimportpartial_p=partial(print,sep="\t")# ABBREVI,S,B,L,D,SET=0,"",False,[],{},set()# ABBREVdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))fori,lineinenumerate(sys.stdin,1):line=line.rstrip("\r\n")l=line# ABBREVI=max(len(line),I)# No wrappingprint(I)Pre and Post codes.-b CODE, --pre CODE,-a CODE, --post CODEThe code specified with-b CODE, --pre CODEwill be added before the loop processing or the main code. This can be useful for declaring variables or performing any necessary setup before entering a loop or executing the main code. The code specified with-a CODE, --post CODEwill be added after the loop processing or the main code. This can be useful for displaying aggregated results or performing any additional actions after the loop or main code execution.$ppprec--pqrn-b'TOTAL = 0'-b'MAX = 0''TOTAL += int(rec[0])''MAX = max(MAX, int(rec[0]))'-a'print(f"TOTAL: {TOTAL}")'-a'print(f"MAX: {MAX}")'importsysfromfunctoolsimportpartialdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))TOTAL=0# PREMAX=0# PREfori,lineinenumerate(sys.stdin,1):line=line.rstrip("\r\n")rec=line.split('\t')TOTAL+=int(rec[0])MAX=max(MAX,int(rec[0]))print(f"TOTAL:{TOTAL}")# POSTprint(f"MAX:{MAX}")# POSTInner loop.-e CODE, --loop-head CODE,-f CODE, --filter CODEIn the loop processing ofline,rec,csv, andfilecommands, the code is added in the following positions:for ... :
    {loop_head}  # Added with the -e CODE, --loop-head CODE option.
    {filter}     # Added with the -f CODE, --filter CODE option.
    {main}       # The main code is added here."loop_head" is added using the-e CODE, --loop-head CODEoption, while "filter" is added using the-f CODE, --filter CODEoption.
Please note that the "loop_head" code is added as-is, while the "loop_filter" is wrapped withif not ({}): continue.$pppline-pqrn-e'line = line.replace("foo", "bar")'-e'line = line.upper()'-f'"BAR" in line''print(line)'importsysfromfunctoolsimportpartialdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))fori,lineinenumerate(sys.stdin,1):line=line.rstrip("\r\n")line=line.replace("foo","bar")# LOOP_HEADline=line.upper()# LOOP_HEADifnot("BAR"inline):continue# FILTERprint(line)# MAINImport modules.-i MODULE, --import MODULEBy using the-i MODULE, --import MODULEoption, you can import any modules. If the value specified with--importis in the form of a sentence, likeimport mathorfrom math import sqrt, it will be added as an import statement just as it is. If only the module name is provided, likemath, it will automatically be given an import statement, such asimport math.ppp text -i zlib -i 'from base64 import b64encode' 'b64encode(zlib.compress(text.encode()))'$ppptext-pqrn-izlib-i'from base64 import b64encode''print(b64encode(zlib.compress(text.encode())))'importsysfromfunctoolsimportpartialimportzlib# <- HEREfrombase64importb64encode# <- HEREdef_print(*args,sep='\t'):iflen(args)==1andisinstance(args[0],(list,tuple)):print(sep.join(str(v)forvinargs[0]))else:print(sep.join(str(v)forvinargs))text=sys.stdin.read()print(b64encode(zlib.compress(text.encode())))Usage example.$seq5|ppp-imath'line, math.sqrt(int(line))'11.021.414213562373095131.732050807568877242.052.23606797749979PagerEnable/Disable PagerIn pypipe, the pager is automatically enabled if the standard output is a tty. To disable the pager, set thePYPIPE_PAGER_ENABLEDenvironment variable tofalse. Additionally, you can enable/disable the pager by specifying the--pagingor--no-pagingoptions. This takes precedence over thePYPIPE_PAGER_ENABLEDsetting. However, if the standard output is not a tty, specifying--pagingwill not enable the pager.Pager commandThe default pager command isless(recommended, tested). You can change the pager command by setting thePYPIPE_PAGERenvironment variable. Iflessis specified as the PAGER, pypipe automatically adds the options set in thePYPIPE_LESS_OPTSenvironment variable. The default value for PYPIPE_LESS_OPTS is-R -F.Pager for-p, --print[!Warning]
When interrupting with Ctrl-C while usingbatas a pager, a display issue has been identified where the terminal output becomes corrupted (terminal command input is no longer visible). Exiting bat withqavoids this issue.You can change the Pager used when the-p, --printoption is specified to a different Pager than the default. For example, by setting thePYPIPE_PRINT_PAGERenvironment variable as shown below, you can usebatto display syntax-highlighted code:export PYPIPE_PRINT_PAGER='bat -l python --file-name=PYPIPE_GENERATED_CODE'Output example when 'bat' is set as the Pager.Pager for-v, --viewSimilarly, by setting thePYPIPE_VIEW_PAGERenvironment variable, you can change the Pager used when the-v, --viewoption is specified to a different Pager than the default. Also, if you do not want to pass color control escape sequences to the Pager, you can disable colors by setting thePYPIPE_VIEW_COLOREDenvironment variable tofalse, thereby avoiding this.