1
Have inputs.conf files in multiple directories that needs to match and parse each stanza and modify the index= to index=secure. This are files type in inputs.conf and also do run the script to locate the inputs file in this dir (_GWAS_pr_linux_t1/local/inputs.conf) to modify the index

In the file

    [WinEventLog://Application]
    checkpointInterval = 5
    current_only = 0
    disabled =0 
    start_from = oldest
    index = 

    [WinEventLog://Security]
    checkpointInterval = 5
    current_only = 0
    disabled =0 
    start_from = oldest
    index = 

    [WinEventLog://System]
    checkpointInterval = 5
    current_only = 0
    disabled =0 
    start_from = oldest
    index = 

    [WinEventLog://ForwardedEvents]
    checkpointInterval = 5
    current_only = 0
    disabled =0 
    start_from = oldest
    index = 

    [WinEventLog://Setup]
    checkpointInterval = 5
    current_only = 0
    disabled =0 
    start_from = oldest
    index = 

I tried with the command

    sed -i -e 's/.*(?s)((\[WinEventLog:\/\/Application|Security|System|ForwardedEvents|Setup\]).*?)(?:(?:\r\n){2}) /index=window inputs.conf

to change to `index=window` for the `Application`, `Security`, `System`, `ForwardedEvents` and `Setup` entry.

In the file

    [monitor:///var/log/cron]
    index=
    sourcetype=linux_secure

    [monitor:///var/log/secure]
    index=
    sourcetype=linux_secure

    [monitor:///var/log/messages]
    index=
    sourcetype=linux

    [monitor:///var/log/spooler]
    index = 
    sourcetype=syslog

    [monitor:///var/log/audit/audit.log]
    sourcetype=syslog
    index=

    [monitor:///var/log//maillog]
    index=
    sourcetype=syslog

I tried command

    sed -i -e 's/.*(?s)((\[monitor\:\/\/\/var\/log\/messages|secure\]).*?)(?:(?:\r*\n){2})' /index=secure *linux*/local/inputs.conf

to change the `index=` line to `index=secure` for the `messages` and `secure` log.


i) Work like a charm but the only issues I'm having right now is that, the 
 script cannot pass through the apps directory and update the index name and 
 most of the apps directory name is in this form.

     _EBPD_pr_linux_w1/local/inputs.conf,
     _EBPD_np_linux_w1/local/inputs.conf,
     _FBPV_pr_liux_e1/local/inputs.conf, 
    _FBPV_np_liux_e1/local/inputs.conf,
     _FBPV_np_windows_e1/local/inputs.conf,
     _FBPV_np_windows_e1/ocal/inputs.conf


ii) Secondly, the most important thing is that, if the app has `np` or `pr` that is how the index name will be updated. For example `index=secure_pr` or `scure_np` or `windows_pr` or `windows_np`.


iii) Another issue is that if there is an existing index name, it does not remove and update to the new index name it just adds to it. For example `index=power` is updated to `index=powersecure` instead of `index=secure`.


iv) I try these but it says "No such file or directory"

    perl -00lpe '$_.="secure_np" if m,/(messages|secure|cron|maillog|spooler|audit/audit\.log)\],' *linux*/local/inputs.conf 

    perl -00lpe '$_.="secure_pr" if m,/(messages|secure|cron|maillog|spooler|audit/audit\.log)],' *linux*/local/inputs.conf 

    perl -00lpe '$_ .= "windows_pr" if m,/(Application|Security|System|ForwardedEvents|Setup)\],' *window*/local/inputs.conf 

    perl -00lpe '$_ .= "windows_nr" if m,/(Application|Security|System|ForwardedEvents|Setup)],' *window*/local/inputs.conf 

closed as unclear what you're asking by Scott, Sparhawk, Nasir Riley, msp9011, G-Man Jun 7 at 5:21

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I updated the sed solution. Did you try it? Do you have any questions about it? – Philippos Jun 5 at 6:45
  • If you get a no such file error, then there is no such file in your current directory. No subdirectory matching *linux*, for example. The rest of your edits seem to be describing a completely different situation to what your original question showed. "cannot pass through the apps directory": what apps dir? What is nr and pr? Why is there an existing index name? Non of your examples had it. We can't guess what your files have, we can only work with what you show. – terdon Jun 6 at 9:40
1

1) For a pattern with many slashes, you should use a different delimiter for the s command to make it more readable (you don't need to escape the slashes then).

2) You seem to be using extended regular expressions, so you have to set the -E option to sed

3) If you use alternate strings for a part of the pattern, you need to surround this with () like (messages|secure)

4) The replacement part (/index=window) needs to be part of the script rather than being separated like an argument.

5) Also, the s command lacks a closing delimiter

6) (?s)and(?:)` are no regular expressions but, perl extensions, so don't use them here. And because the colon doesn't have a special meaning here, you don't need to escape it (thanks, @Stéphane Chazelas)

7) sed is working line by line, so your \n is never going to match until you join lines (which you don't do)

Now I dare to guess what you tried to do: For the messages and secure log, change the following index= line to index=secure. Correct?

So your command is s/index=/index=secure/. But you only want to apply it to certain groups. For this purpose, sed has a filtering option to apply commands only to lines (or group of lines) that match the filter. One way to address lines a pattern to be matched. If you want to adress a range of lines, you give two addresses (starting and stopping address), separated by a comma:

sed -E '\_\[WinEventLog://(Application|Security|System|ForwardedEvents|Setup)\]_,/index *=/s/index =/index = window/' inputs.conf

On the second command I can show how to further simplify the command: You can drop the matching pattern in the s command. This means that the last pattern is used again, which happends to be the second address of the filter range, so no need to repeat it.

And instead of repeating the pattern in the replacement, you can write &, which will insert the whole match:

sed -i -E '\_\[monitor:///var/log/(messages|secure)\]_,/index=/s//&secure/' *linux*/local/inputs.conf

A final hint: Don't use the -i option until you are satislied with the result. You can easily mess up your file that way, especeally while you are unexperienced with the tool.

Update

WIth the updated question it seems to be possible that the already is some index=foo setting that needs to be replaced. Simply change the replacement:

sed -E '/(Application|Security|System|ForwardedEvents|Setup)]/,/index *=.*/s//index = window/' inputs.conf

and

sed -i -E '/messages]|secure]/,/index *=.*/s//index=secure/' *linux*/local/inputs.conf

(further simplification of the pattern suggested by terdon)

  • (?s), (?:...), .*? are perl operators – Stéphane Chazelas Jun 3 at 5:48
  • I was afraid so, thank you. I did change my answer accordingly. I wonder why the OP wants to use sed at all, trying to "program" sed like it was perl ... – Philippos Jun 3 at 6:00
  • @user10965163 You wrote the perl stuff didn't succeed, but how about this sed solution? – Philippos Jun 11 at 18:24
0

This would be much easier to do in Perl. The perl executable has something called "paragraph mode" (-00) in which a "line" is defined by two consecutive \n characters (so an empty line). This enables perl to work with paragraphs instead of lines. So you could simply do:

$ perl -00pe 'if(m,^\[WinEventLog://(Application|Security|System|ForwardedEvents|Setup)\],){s/(index\s*=)\s*[^\n]*/$1 window inputs.conf\n\n/}' file1
[WinEventLog://Application]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Security]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://System]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://ForwardedEvents]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Setup]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

And:

$ perl -00pe 'if(m,^\[monitor:///var/log/(messages|secure)\],){s/(index\s*=)\s*[^\n]*/$1 secure\n\n/}' file2
[monitor:///var/log/cron]
sourcetype=linux_secure
index=

[monitor:///var/log/secure]
sourcetype=linux_secure
index= secure

[monitor:///var/log/messages]
sourcetype=linux
index= secure

[monitor:///var/log/spooler]
sourcetype=syslog
index = 

[monitor:///var/log/audit/audit.log]
sourcetype=syslog
index=

[monitor:///var/log//maillog]
sourcetype=syslog
index=

However, since your files seem to have a pretty stable format, you could further simplify to:

$ perl -00lpe '$_ .= "window inputs.conf" if m,//(Application|Security|System|ForwardedEvents|Setup)\],;' file1
[WinEventLog://Application]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Security]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://System]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://ForwardedEvents]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Setup]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

And:

$ perl -00lpe '$_.="secure" if m,/(messages|secure)\],' file2
[monitor:///var/log/cron]
sourcetype=linux_secure
index=

[monitor:///var/log/secure]
sourcetype=linux_secure
index=secure

[monitor:///var/log/messages]
sourcetype=linux
index=secure

[monitor:///var/log/spooler]
sourcetype=syslog
index = 

[monitor:///var/log/audit/audit.log]
sourcetype=syslog
index=

[monitor:///var/log//maillog]
sourcetype=syslog
index=
  • While I agree that the OP should probably choose perl as he seems to be experienced with it while not having basic understanding of sed, I disagree with "much easier". Comparing the scripts, there is nothing easier. You can also apply the assumtions of your last script like '/messages]|secure]/,/x=/s//&secure/'. Addressing a range is as easy as the paragraph mode. I think it's more a matter of what you are used to. – Philippos Jun 4 at 6:47
  • @user10965163 sorry, but I don't understand what you mean. However, it sounds like a new issue so please post a separate question about that. – terdon Jun 4 at 15:59
  • @Philippos what is easier is that perl has the paragraph mode which allows you to deal with multiline strings like this very easily. And yes, I find perl -00lpe '$_.="secure" if m,/(messages|secure)\],' far easier and cleaner than sed -i -E '\_\[monitor:///var/log/(messages|secure)\]_,/index=/s//&secure/' but that may be a question of personal preference. – terdon Jun 4 at 16:02
  • @user10965163 I can't understand what you have done in the comments. Please either i) update your existing question explaining what you tried and how it failed or ii) ask a new question or iii) ping me in /dev/chat. – terdon Jun 4 at 16:58
  • @user10965163 once again: please don't do this in the comments. It is impossible to understand what you did and that's not how this site works. Either edit your question to add what you did or, better, ask a new one. – terdon Jun 4 at 22:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.