提取动态输入的特定部分,然后将它们组合在一起?

huangapple go评论66阅读模式
英文:

how to extract specific parts from a dynamic input and then put them together?

问题

cmd1 = "dir"
args1 = "/a"
path = "c:\\users\\"
cmd2 = '| find "stuff"'

cmd3 = "more"
path2 = "c:\\windows\\win.ini"
cmd4 = '| findstr "fonts"'

cmd5 = "certutil.exe"
args2 = "-encode \\dir\\file"
extra_cmds = "& something"
英文:

Having in input a command, i would like to extract using python in a separate way the command, the path involved, the args and the extra commands concatenated, so that i can work with every single piece if needed, and then build them back all together

so, for example:

dir /a c:\users\ | find "stuff"
cmd1 = "dir"
args1 = "/a"
path =  "c:\\users\\"
cmd2 = '| find "stuff"'

this would be an easy task if the commands would be always the same or with the same patterns, but how can I do it if they are always different and with a different syntax?

some more examples:

more c:\windows\win.ini | findstr "fonts"
certutil.exe -encode \dir\file & something

答案1

得分: 1

这是有趣的!这里是我的尝试:

import re

examples = [
    'dir /a c:\\users\\ | find "stuff"',
    'more c:\\windows\\win.ini | findstr "fonts"',
    'certutil.exe -encode \\dir\\file & something',
    'command -option1 -option2 -option3',
    'command "path with spaces" -option',
    'command > output.txt',
    'command "path with \'nested\' quotes" [optional argument]',
    'echo "This is a test" | find /v "exclude"',
    'python script.py arg1 arg2 --option',
    'echo $HOME',
    'dir /s /b | findstr /r "\.txt$"',
    'command1 | command2 | command3',
    'command1 && command2 || command3',
    'command1 | command2 > output.txt 2>&1',
    'command arg1^&arg2 arg3',
    'echo ^<output^>',
    'command1 arg1 | command2 arg2',
    'command -option="value"',
    'command --long-option arg1 arg2',
    'command [optional argument] -option=value',
    'command arg1 ^& command2 arg2',
    'command "path with spaces" | find "search phrase"',
    'python -c "print(2 + 2)"',
    'curl -X POST -d @data.txt http://example.com/api',
    'grep -r "pattern" /path/to/search --exclude-dir=dir',
    'ls -l | awk \'{print $1, $2}\'',
    'command < input.txt',
    'command arg1 -f file.txt',
    'command "string with $special$ chars"',
    'command --verbose --debug',
    'command arg1 ^> output.txt',
    'command [optional argument1] --flag --option=value [optional argument2]',
]

import re

def process_command(command):
    command = re.split(r" \| | & |&&|\|\|", command)
    print(command)
    for com in command:
        com = com.split(" ")
        print(f"Command: {com[0]}")
        string_parts = []
        i = 1
        in_long_string = False
        quote_mark = None
        arg_number = 0
        option_number = 0
        while i < len(com):
            if in_long_string:
                if quote_mark == com[i][-1]:
                    string_parts.append(com[i])
                    print(f"String: {' '.join(string_parts)}")
                    string_parts = []
                    in_long_string = False
                else:
                    string_parts.append(com[i])
            elif re.match(r"^[a-zA-Z]:\\|^\\", com[i]): # if it starts with a letter then :// or starts with \, it's a path
                print(f"Path: {com[i]}")
            elif re.match(r"^/|-", com[i]):  # if it starts with / or -, it's an option
                option_number += 1
                print(f"Option {option_number}: {com[i]}")          
            elif re.match(r"^('|\").+('|\")$", com[i]): # if it's surrounded by quotes, it's a string
                print(f"String: {com[i]}")
            elif re.match(r"^('|\").*$", com[i]): # if it starts with a quote mark, it's the start of a long string
                string_parts.append(com[i])
                quote_mark = com[i][0]
                in_long_string = True
            elif re.match(r">$", com[i]): # if it ends in a >, it's an output thing
                print(f"Output: {com[i+1]}")
                i += 1
            elif re.match(r"<$", com[i]): # likewise with inputs
                print(f"Input: {com[i+1]}")
            else: # otherwise it's some other kind of argument
                arg_number += 1
                print(f"Argument {arg_number}: {com[i]}")
            i += 1

[process_command(command) for command in examples]

如果有任何问题,请附带更多示例的注释。

英文:

This was fun! Here is my attempt:

import re
examples = [
&#39;dir /a c:\\users\\ | find &quot;stuff&quot;&#39;,
&#39;more c:\\windows\\win.ini | findstr &quot;fonts&quot;&#39;,
&#39;certutil.exe -encode \\dir\\file &amp; something&#39;,
&#39;command -option1 -option2 -option3&#39;,
&#39;command &quot;path with spaces&quot; -option&#39;,
&#39;command &gt; output.txt&#39;,
&#39;command &quot;path with \&#39;nested\&#39; quotes&quot; [optional argument]&#39;,
&#39;echo &quot;This is a test&quot; | find /v &quot;exclude&quot;&#39;,
&#39;python script.py arg1 arg2 --option&#39;,
&#39;echo $HOME&#39;,
&#39;dir /s /b | findstr /r &quot;\.txt$&quot;&#39;,
&#39;command1 | command2 | command3&#39;,
&#39;command1 &amp;&amp; command2 || command3&#39;,
&#39;command1 | command2 &gt; output.txt 2&gt;&amp;1&#39;,
&#39;command arg1^&amp;arg2 arg3&#39;,
&#39;echo ^&lt;output^&gt;&#39;,
&#39;command1 arg1 ^| command2 arg2&#39;,
&#39;command -option=&quot;value&quot;&#39;,
&#39;command --long-option arg1 arg2&#39;,
&#39;command [optional argument] -option=value&#39;,
&#39;command arg1 ^&amp; command2 arg2&#39;,
&#39;command &quot;path with spaces&quot; ^| find &quot;search phrase&quot;&#39;,
&#39;python -c &quot;print(2 + 2)&quot;&#39;,
&#39;curl -X POST -d @data.txt http://example.com/api&#39;,
&#39;grep -r &quot;pattern&quot; /path/to/search --exclude-dir=dir&#39;,
&#39;ls -l | awk \&#39;{print $1, $2}\&#39;&#39;,
&#39;command &lt; input.txt&#39;,                        
&#39;command arg1 -f file.txt&#39;,                    
&#39;command &quot;string with $special$ chars&quot;&#39;,        
&#39;command --verbose --debug&#39;,                    
&#39;command arg1 ^&gt; output.txt&#39;,                   
&#39;command [optional argument1] --flag --option=value [optional argument2]&#39;,  
]
import re
def process_command(command):
command = re.split(r&quot; \| | &amp; |&amp;&amp;|\|\|&quot;, command)
print(command)
for com in command:
com = com.split(&quot; &quot;)
print(f&quot;Command: {com[0]}&quot;)
string_parts = []
i = 1
in_long_string = False
quote_mark = None
arg_number = 0
option_number = 0
while i &lt; len(com):
if in_long_string:
if quote_mark == com[i][-1]:
string_parts.append(com[i])
print(f&quot;String: {&#39; &#39;.join(string_parts)}&quot;)
string_parts = []
in_long_string = False
else:
string_parts.append(com[i])
elif re.match(r&quot;^[a-zA-Z]:\\|^\\&quot;, com[i]): # if it starts with a letter then :// or starts with \, it&#39;s a path
print(f&quot;Path: {com[i]}&quot;)
elif re.match(r&quot;^/|-&quot;, com[i]):  # if it starts with / or -, it&#39;s an option
option_number += 1
print(f&quot;Option {option_number}: {com[i]}&quot;)          
elif re.match(r&quot;^(\&quot;|\&#39;).+(\&quot;|\&#39;)$&quot;, com[i]): # if it&#39;s surrounded by quotes, it&#39;s a string
print(f&quot;String: {com[i]}&quot;)
elif re.match(r&quot;^(\&quot;|\&#39;).*$&quot;, com[i]): # if it starts with a quote mark, it&#39;s the start of a long string
string_parts.append(com[i])
quote_mark = com[i][0]
in_long_string = True
elif re.match(r&quot;&gt;$&quot;, com[i]): # if it ends in a &gt;, it&#39;s an output thing
print(f&quot;Output: {com[i+1]}&quot;)
i += 1
elif re.match(r&quot;&lt;$&quot;, com[i]): # likewise with inputs
print(f&quot;Input: {com[i+1]}&quot;)
else: # otherwise it&#39;s some other kind of argument
arg_number += 1
print(f&quot;Argument {arg_number}: {com[i]}&quot;)
i += 1
[process_command(command) for command in examples]

Comment with some more examples if it doesn't work for anything

huangapple
  • 本文由 发表于 2023年7月4日 21:06:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76612973.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定