{"id":20315236,"url":"https://github.com/sysread/app-tailor","last_synced_at":"2025-06-17T09:33:13.733Z","repository":{"id":56837389,"uuid":"255367095","full_name":"sysread/App-Tailor","owner":"sysread","description":"Easily tailor terminal output to meet your needs with simple perl scripts","archived":false,"fork":false,"pushed_at":"2020-04-14T19:49:11.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-11T12:59:37.381Z","etag":null,"topics":["colorize","console","filter","grep","inputstream","log","logging","outputstream","perl","perl5","terminal"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sysread.png","metadata":{"files":{"readme":"README.pod","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-13T15:31:39.000Z","updated_at":"2020-04-14T19:49:14.000Z","dependencies_parsed_at":"2022-09-09T17:21:53.686Z","dependency_job_id":null,"html_url":"https://github.com/sysread/App-Tailor","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/sysread/App-Tailor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysread%2FApp-Tailor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysread%2FApp-Tailor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysread%2FApp-Tailor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysread%2FApp-Tailor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sysread","download_url":"https://codeload.github.com/sysread/App-Tailor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysread%2FApp-Tailor/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260328800,"owners_count":22992768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["colorize","console","filter","grep","inputstream","log","logging","outputstream","perl","perl5","terminal"],"created_at":"2024-11-14T18:18:25.183Z","updated_at":"2025-06-17T09:33:13.694Z","avatar_url":"https://github.com/sysread.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"=pod\n\n=encoding UTF-8\n\n=head1 NAME\n\nApp::Tailor - easily tailor terminal output to meet your needs\n\n=head1 VERSION\n\nversion 0.03\n\n=head1 SYNOPSIS\n\n  #-------------------------------------------------------------------------------\n  # file: my-filter.pl\n  #-------------------------------------------------------------------------------\n  use App::Tailor;\n  use JSON::XS qw(decode_json);\n\n  # ignore lines containing /ping\n  ignore qr/\\/ping/;\n\n  # parse JSON-encoded lines\n  modify qr/^{.*/ =\u003e sub{\n    my $data = decode_json $_;\n    my $msg  = $data-\u003e{message};\n    my $ts   = $data-\u003e{timestamp};\n    my $pri  = $data-\u003e{priority};\n    return \"[$ts] [$pri] $msg\";\n  };\n\n  # make error lines white on red\n  colorize qr/\\[ERROR\\]/ =\u003e qw(white on_red);\n\n  # tail STDIN\n  tail;\n\n  #-------------------------------------------------------------------------------\n  # using your filter\n  #-------------------------------------------------------------------------------\n  $ tail /var/log/some-log-file | my-filter.pl\n\n=head1 DESCRIPTION\n\nThere are a number of programs available to filter, colorize, and modify\nstreaming output. Generating exactly the desired output often requires\npipe-chaining many calls to grep, cut, cols, jq, et al, or using an inflexible\nconfig file or files, often in tandem with a long chain of piped commands.\n\nC\u003cApp::Tailor\u003e makes it easier to do this by making it trivial to write quick\nscripts to filter, alter, and colorize output exactly as needed.\n\n=head1 EXPORTS\n\n=head2 ignore\n\nAccepts a regex which, when matched, will cause a line of input to be ignored.\n\n  ignore qr/foo/;       # ignore any line containing 'foo'\n  ignore qr/foo(?=bar)  # ignore any line containing 'foo' followed by 'bar'\n\nIgnored rules are applied to each line of input B\u003cFIRST\u003e.\n\n=head2 modify\n\nAccepts a regex which, when matched, will cause a the first capture in the\ninput to by modified. If the second argument is a string, it will replace the\nfirst capture in the matching regex. If the second argument is a function, it\nwill be called on the first capture's matching text and its return value will\nreplace the captured text in the line's output. For convenience, C\u003c$_\u003e is\nassigned to the value of the captured text.\n\nIf multiple matching rules exist, they are applied in the order in which they\nwere defined.\n\n  modify qr/foo/ =\u003e sub{ uc $_ };   # foo =\u003e FOO\n  modify qr/FOO/ =\u003e 'FOOL';         # FOO =\u003e 'FOOL';\n\nIndexed and named captures may be modified using the normal patterns, with the\ncaveat that care must be taken to ensure that a replacement string is not\ninterpolated as part of the definition. The rule will do a string eval on the\nmodifier regex and modifier string so that the following will work:\n\n  # capture groups\n  modify qr/(a) (b)/ =\u003e sub{ \"$1 -\u003e $2\" };\n  # interpolation is   ______^________^\n  # ok in a subroutine\n\n  modify qr/(a) (b)/ =\u003e '$1 -\u003e $2'; \n  # but not when the ___^________^\n  # replacement is a\n  # string\n\n  # named captures\n  modify qr/(?\u003cfirst\u003ea) (?\u003csecond\u003eb)/ =\u003e sub{\n    return $+{first} . ' -\u003e ' . $+{second};\n  };\n\nModifier rules are applied to each line of input B\u003cSECOND\u003e.\n\n=head2 colorize\n\nAccepts a regex which, when matched, will cause the entire match to be\ncolorized using ANSI color escapes. The second argument is a list of color\nlabels to be applied. See L\u003cTerm::ANSIColor/Function-Interface\u003e for acceptable\nlabels.\n\n  # \"foo\" has fg:red, bg:white\n  colorize qr/foo/ =\u003e qw(red on_white);\n\n  # \"foo\" when followed by \"bar\" will become painful to look at;\n  # \"bar\" itself is not colorized.\n  colorize qr/foo(?=bar) =\u003e qw(bright_white on_bright_magenta);\n\nColorizing rules are applied to each line of input B\u003cLAST\u003e.\n\n=head2 tail\n\nTails an input stream. By default, reads from C\u003cSTDIN\u003e and prints to C\u003cSTDOUT\u003e,\napplying any rules defined with L\u003c/ignore\u003e, L\u003c/modify\u003e, and L\u003c/colorize\u003e to the\nemitted output.\n\nInput and output streams may be overridden by passing positional parameters,\nboth of which are optional:\n\n  tail $in, $out;\n\n=head2 itail\n\nReturns a function which reads from an input stream and returns lines of text\nafter applying any rules defined with L\u003c/ignore\u003e, L\u003c/modify\u003e, and L\u003c/colorize\u003e\nto the emitted output. Returns C\u003cundef\u003e when the input stream is closed.\n\nAs with L\u003c/tail\u003e, the default input stream (C\u003cSTDIN\u003e) may be overridden.\n\n  my $tailor = itail $fh;\n\n  while (defined(my $line = $tailor-\u003e())) {\n    print $line;\n  }\n\n=head2 reset_rules\n\nClears all defined rules, resetting filtering state to initial load state.\n\n=head1 DEBUGGING\n\nTo help with troubleshooting scripts built with C\u003cApp::Tailor\u003e, verbose logging\nmay be enabled by setting the environment variable C\u003cAPP_TAILOR_DEBUG\u003e to a\ntrue value or by setting the value of C\u003c$App::Tailor::DEBUG\u003e to a true value\ndirectly.\n\n=head1 AUTHOR\n\nJeff Ober \u003csysread@fastmail.fm\u003e\n\n=head1 COPYRIGHT AND LICENSE\n\nThis software is copyright (c) 2020 by Jeff Ober.\n\nThis is free software; you can redistribute it and/or modify it under\nthe same terms as the Perl 5 programming language system itself.\n\n=cut\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsysread%2Fapp-tailor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsysread%2Fapp-tailor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsysread%2Fapp-tailor/lists"}