allow several space-separated commands
This commit is contained in:
parent
c06bec5a90
commit
ed3d52b038
2 changed files with 51 additions and 15 deletions
40
README.md
40
README.md
|
|
@ -2,3 +2,43 @@ paternoster
|
||||||
===========
|
===========
|
||||||
|
|
||||||
A command line tool that call the given command for each input line matching the given regular expression pattern.
|
A command line tool that call the given command for each input line matching the given regular expression pattern.
|
||||||
|
|
||||||
|
|
||||||
|
## SYNOPSIS
|
||||||
|
|
||||||
|
`paternoster` [-h]
|
||||||
|
|
||||||
|
`paternoster` [-w] PATTERN COMMAND(S)
|
||||||
|
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
|
||||||
|
`paternoster` read lines of text stream on the standard input and call
|
||||||
|
*COMMAND(S)* for lines matching a given regular expression *PATTERN*.
|
||||||
|
|
||||||
|
If groups are specified in the regular expression pattern, only them are taken
|
||||||
|
into account, else the whole matching pattern is considered.
|
||||||
|
|
||||||
|
You can specify several commands when using groups by separating them with
|
||||||
|
spaces. If you indicate more commands than groups, the last ones will be
|
||||||
|
silently ignored. If you ask for fewer commands, the last one will be
|
||||||
|
duplicated across remaining groups.
|
||||||
|
|
||||||
|
|
||||||
|
## EXAMPLES
|
||||||
|
|
||||||
|
* Make the speakers beep for every FIXME found in a source code:
|
||||||
|
`cat source.ext | paternoster "FIXME" "beep"
|
||||||
|
|
||||||
|
* Play a sound for each error or warning on a compiler output (you must have the
|
||||||
|
corresponding wav files somewhere in you path):
|
||||||
|
`make 2>&1 | paternoster ".*(error|warning): .*$" "play %s.wav"`
|
||||||
|
|
||||||
|
* Say out loud the error in a compiler output:
|
||||||
|
`make 2>&1 | paternoster ".*(error: .*)$" "espeak --punct=';{}()' '%s'"`
|
||||||
|
|
||||||
|
|
||||||
|
## CREDITS
|
||||||
|
|
||||||
|
* Error sound by tcpp, licensed under CC-BY: http://www.freesound.org/people/tcpp/sounds/151309/
|
||||||
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,37 +16,33 @@ def call( cmd, text, nowait=False ):
|
||||||
# If there is a string formatting mark
|
# If there is a string formatting mark
|
||||||
try:
|
try:
|
||||||
# put the matching text in it
|
# put the matching text in it
|
||||||
order = str(cmd % text).split()
|
behest = cmd % text
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# else, do not
|
# else, do not
|
||||||
order = cmd.split()
|
behest = cmd
|
||||||
|
|
||||||
# Join the command parts in the subprocess list format: [command,args]
|
|
||||||
behest = [order[0]," ".join(order[1:])]
|
|
||||||
|
|
||||||
with open("/dev/null") as dev_null:
|
with open("/dev/null") as dev_null:
|
||||||
if nowait:
|
if nowait:
|
||||||
subprocess.Popen( behest, stdout=sys.stdout, stderr=dev_null )
|
subprocess.Popen( behest, stdout=sys.stdout, stderr=dev_null, shell=True )
|
||||||
else:
|
else:
|
||||||
subprocess.call( behest, stdout=sys.stdout, stderr=dev_null )
|
subprocess.call( behest, stdout=sys.stdout, stderr=dev_null, shell=True )
|
||||||
|
|
||||||
|
|
||||||
def parse( text, pattern, cmd="", nowait=False ):
|
def parse( text, pattern, cmd=[""], nowait=False ):
|
||||||
|
|
||||||
regex = re.compile(pattern)
|
regex = re.compile(pattern)
|
||||||
for match in regex.finditer(text):
|
for match in regex.finditer(text):
|
||||||
|
|
||||||
# If no groups are specified
|
# If no groups are specified
|
||||||
if not match.groups():
|
if not match.groups():
|
||||||
call( cmd, text, nowait )
|
call( cmd[0], text, nowait )
|
||||||
|
|
||||||
else:
|
else:
|
||||||
nb_groups = len(match.groups())
|
nb_groups = len(match.groups())
|
||||||
|
|
||||||
# Build a list of colors that match the number of grouped,
|
# Build a list of colors that match the number of grouped,
|
||||||
# If there is not enough commands, duplicate the last one.
|
# If there is not enough commands, duplicate the last one.
|
||||||
cmds_l = cmd.split(",")
|
group_cmds = cmd + [cmd[-1]] * (nb_groups - len(cmd))
|
||||||
group_cmds = cmds_l + [cmds_l[-1]] * (nb_groups - len(cmds_l))
|
|
||||||
|
|
||||||
# For each group index.
|
# For each group index.
|
||||||
# Note that match.groups returns a tuple (thus being indexed in [0,n[),
|
# Note that match.groups returns a tuple (thus being indexed in [0,n[),
|
||||||
|
|
@ -109,18 +105,18 @@ if __name__ == "__main__":
|
||||||
parser.add_argument("pattern", metavar="REGEX", type=str, nargs=1,
|
parser.add_argument("pattern", metavar="REGEX", type=str, nargs=1,
|
||||||
help="A regular expression")
|
help="A regular expression")
|
||||||
|
|
||||||
parser.add_argument("command", metavar="CMD", type=str, nargs='?',
|
parser.add_argument("commands", metavar="CMD", type=str, nargs="+",
|
||||||
default="espeak %s",
|
default="espeak %s",
|
||||||
help="The command to run if REGEX match. \
|
help="The command to run if REGEX match. \
|
||||||
If CMD contains a string formating placefolder (like \"%%s\"), \
|
If CMD contains a string formating placefolder (like \"%%s\"), \
|
||||||
it will be replaced by the matching text. \
|
it will be replaced by the matching text. \
|
||||||
Multiple commands may be specified as a list of comma-separated values. \
|
Multiple commands may be specified as a list of space-separated strings. \
|
||||||
Commands will then be called for each matching group within REGEX.")
|
Each command will then be called for each corresponding matching group within REGEX.")
|
||||||
|
|
||||||
parser.add_argument("-w", "--no-wait", action="store_true",
|
parser.add_argument("-w", "--no-wait", action="store_true",
|
||||||
help="Don't wait for the end of the current command before calling the next one.")
|
help="Don't wait for the end of the current command before calling the next one.")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
map_write( sys.stdin, sys.stdout, parse, args.pattern[0], args.command, args.no_wait )
|
map_write( sys.stdin, sys.stdout, parse, args.pattern[0], args.commands, args.no_wait )
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue