I'm trying to delete a section elasticsearch { * } from a configuration file due to lack other options.
output {
if [env] {
if [containerimage] and [containerimage] != "apache" {
file {
path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
}
elasticsearch {
hosts => ["{{elasticsearch/host}}:{{elasticsearch/port}}"]
template_overwrite => true
}
}
}
}
I tried to reverse the sed command found on stackoverflow but it deletes ending } from configuration files too.
[root#indexer conf.d]# sed '/{/{:1; /}/!{N; b1}; /elasticsearch/!p}; d' example
output {
if [env] {
if [containerimage] and [containerimage] != "apache" {
file {
path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
It may be due to }} in to cfg that must be there. Any ideas to overcome this problem? Thanks in advance
Edit:
some other experiment:
sed '/elasticsearch {/{:1; /}/!{N; b1} }; /elasticsearch/!p; d' example
output {
if [env] {
if [containerimage] and [containerimage] != "apache" {
file {
path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
}
template_overwrite => true
}
}
}
}
But leaves template_overwrite and some closing braces.
This might work for you (GNU sed):
sed '/^\s*elasticsearch {$/{:a;N;/^\s*}$/M!ba;d}' file
Gather up the lines beginning elasticsearch { and ending } and delete them.
N.B. This uses the M flag for a multiline match for the end condition which is GNU sed specific. An alternative:
sed -n '/^\s*elasticsearch {$/{:a;n;/^\s*}$/!ba;d};p' file
Here's one in awk:
awk '
BEGIN {
RS="^$" # read in the whole file
c=1 # brace counter
}
{
match($0,/\n? *elasticsearch \{/) # find the start of string to remove
print substr($0,1,RSTART-1) # RUNNING OUT OF BATTERY
$0=substr($0,RSTART+RLENGTH)
while(c>0) {
match($0,/(\{|\} *\n*)/)
if(substr($0,RSTART,1)=="{")
c++
else
c--
$0=substr($0,RSTART+RLENGTH)
}
print
}' file
Output:
output {
if [env] {
if [containerimage] and [containerimage] != "apache" {
file {
path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
}
}
}
}
Only tested with provided data.
Is this all you're trying to do?
$ sed '/elasticsearch[[:space:]]*{/,/^[[:space:]]*}/d' file
output {
if [env] {
if [containerimage] and [containerimage] != "apache" {
file {
path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
}
}
}
}
The above will work with any POSIX sed. If that's not all you need then please edit your question to show a more truly representative example so we can help you. FWIW I wouldn't really do the above as it's not extensible if/when your requirements vary slightly, I'd do this instead:
$ awk '/elasticsearch[[:space:]]*{/{f=1} !f; /^[[:space:]]*}/{f=0}' file
output {
if [env] {
if [containerimage] and [containerimage] != "apache" {
file {
path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
}
}
}
}
Related
I'm using the following awk command to replace strings in a swift source file:
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" "$file" > ./temp
Trying not to edit commented out values. At a minimum, need to ignore lines that start with "//" but it seems possible to ignore inline comments (e.g. when the line is only partially commented like "MATCH // <- Ok" or "foo // MATCH <- Not Ok").
Something like...
s=index($0,old) && !($0 =~ "^//") { ... }
Sample Input:
old="\"Some \(value) with %# special \n characters\""
new="\"some_key\".localized"
file {contents}...
/// - Returns: "Some \(value) with %# special \n characters"
static let someValue = "Some \(value) with %# special \n characters" // <-- This should change
static let otherValue = "This line does NOT change" // "Some \(value) with %# special \n characters"
Expected Output:
/// - Returns: "Some \(value) with %# special \n characters"
static let someValue = "some_key".localized // <-- This should change
static let otherValue = "This line does NOT change" // "Some \(value) with %# special \n characters"
EDIT
Although #RavinderSingh13's answer did not match expected output, it was close and I used it to modify my command like so:
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
s=index($0,old) { if (!(match($0,/.*\/\//))) $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }' "$old" "$new" "$file"
This meets the original requirement, but ignores ANY line that has two slashes. This is problematic, because it doesn't support in line comments (e.g. the above command would not edit any of the sample input; unless the "// <-- This should change" comment is removed. If no one replies, I'll use this as the answer, but I'll wait a day or so in case someone posts a version of the command that meets all the requirements. Will accept that answer.
It would be something like this...
s=index($0,old) { if (!(match($0,/.*\/\//)) || (match($0,/"$old".*\/\//))) $0 = substr($0,1,s-1) new substr($0,s+len) }
Considering that you want skip all lines which start from // and also you want to print contents which comes before // for in between inline comments. Fair warning not tested since NO samples given.
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
/^\/\//{ next }
match($0,/.*\/\//){ $0 = substr($0,RSTART,RLENGTH-2) }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" "$file" > ./temp
Above will neglect lines which are starting with // if you want to print them then do following.
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
/^\/\//{ print; next }
match($0,/.*\/\//){ $0 = substr($0,RSTART,RLENGTH-2) }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" "$file" > ./temp
Only look for "old" in the part of each line before the start of any comment, e.g.:
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
{ preCmt = $0; sub("//.*","", preCmt) }
s=index(preCmt,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" file
/// - Returns: "Some \(value) with %# special \n characters"
static let someValue = "some_key".localized // <-- This should change
static let otherValue = "This line does NOT change" // "Some \(value) with %# special \n characters
I find there are many ways to skin a cat, but what is the preferred style writing routes
def leaderboardGet1(): Route = {
get {
pathEnd {
parameter('name) { name =>
complete(. . .)
} ~
complete(. . .)
} ~
pathPrefix(base64identifier) { leaderboardIdentifier =>
pathEnd {
complete(. . .)
} ~
pathPrefix(base64identifier) { memberIdentifier =>
pathEnd {
complete(. . .)
}
}
} ~
complete {
HttpResponse(BadRequest, entity = "Bad GET /leaderboard request")
}
}
}
I will call the first style match-least-first, and the the second style match-most-first. If someone knows better names please let me know.
def leaderboardGet2(): Route = {
get {
pathPrefix(base64identifier) { leaderboardIdentifier =>
pathPrefix(base64identifier) { memberIdentifier =>
pathEnd {
complete(. . .)
}
} ~
pathEnd {
complete(. . .)
}
}
} ~
pathEnd {
parameter('name) { name =>
complete(. . .)
}
} ~
complete(. . .)
} ~
complete {
HttpResponse(BadRequest, entity = "Bad GET /leaderboard request")
}
}
}
I am looking more for readability/maintainability in coding style, but don't have a strong sense. I like the second style a little better as I can more easily see what the longest URL would be, but no other opinions.
There might be some performance considerations, depending statistically on what URLs are requested most, but I doubt that is significant.
Are there some other considerations pertaining to functional programming style, idiomatic Scala, idiomatic Spray routing, etc.?
None of the styles above give you any advantage on code maintainability. If I had to pick one of this, I'd go with "match-most-first" approach. The reason for this is the first matched route is executed, so the more specific route definitions should go first.
Take this as an example
get {
pathPrefix(JavaUUID) { id =>
pathEnd {
complete(s"Got UUID $id")
}
} ~ pathPrefix(Segment) { someOtherId =>
pathEnd {
complete(s"Got Other ID $someOtherId")
}
}
}
So, if pathPrefix(Segment) is handled first, pathPrefix(JavaUUID) will never get a result as it is matched by pathPrefix(Segment) too.
In my Mojolicious app I have this:
if (-f $file_path1) {
app->log->debug("file1 exists: $file_path1");
# ...........
} else {
app->log->debug("file1 doesn't exist: $file_path1; creating....\r\n");
Regardless of its presence, it never prints "file1 doesn't exist"
When I remove it, it still doesn't print that it doesn't exist.
How can this be?
First of all, to check if a file exists, you want -e or stat (not -f).
Secondly, you treat "exists but isn't a plain file" results, "file not found" errors and other errors as "file not found" errors. If things aren't working as you expect, you should check more closely what is error is actually being returned!
if (-e $file_path1) {
app->log->debug("\"$file_path1\" already exists.\n");
}
elsif ($!{ENOENT}) {
app->log->debug("\"$file_path1\" doesn't exist. Creating...\n");
}
else {
app->log->debug("Error stating \"$file_path1\": $!\n");
}
or
if (stat($file_path1)) {
app->log->debug("\"$file_path1\" already exists.\n");
}
elsif ($!{ENOENT}) {
app->log->debug("\"$file_path1\" doesn't exist. Creating...\n");
}
else {
app->log->debug("Error stating \"$file_path1\": $!\n");
}
If you were using -f because you also wanted to check if it's a plain file, you can use the following:
my $rv = -f $file_path1;
if (defined($rv)) {
if ($rv) {
app->log->debug("\"$file_path1\" already exists.\n");
} else {
app->log->debug("\"$file_path1\" already exists, but isn't a plain file.\n");
}
} else {
if ($!{ENOENT}) {
app->log->debug("\"$file_path1\" doesn't exist. Creating...\n");
} else {
app->log->debug("Error stating \"$file_path1\": $!\n");
}
}
or
if (stat($file_path1)) {
if (-f _) {
app->log->debug("\"$file_path1\" already exists.\n");
} else {
app->log->debug("\"$file_path1\" already exists, but isn't a plain file.\n");
}
} else {
if ($!{ENOENT}) {
app->log->debug("\"$file_path1\" doesn't exist. Creating...\n");
} else {
app->log->debug("Error stating \"$file_path1\": $!\n");
}
}
Assuming you're right and the problem isn't really that the file doesn't exist, any of these snippets will get the reason the file can't be stated. A permission problem, perhaps?
If my snippets tell you that the file doesn't exist, then it really doesn't. Make sure the value you are passing to stat/-e/-f contains what you think it does (e.g. no trailing spaces, CR or LF). If the path is a relative path, it could also be that you are making incorrect assumptions about the current work directory.
Below is the example of my file,
signal {
{
ab
cd
}
"m_1_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"m_0_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
"m_0_clk" {
Data S Mk {
Active Up;
}
}
"m_1_clk" {
Data S Mk {
Active Up;
}
}
}
I am expecting the output from above file to be:
signal {
{
ab
cd
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
}
Hi,
Above is the example of my file
I would like to delete pattern which matches the next pattern which is calling in the next line.
Trying to search the specific pattern for deleting the lines which it should not be present in my file.
Need to search the specific pattern with new pattern in the next line. because first line is calling in multiple loops. so should grep specific pattern of all the content.
I tried using the below command in tcl its not working. could anyone help me on this,
below is the sed command used in tcl
exec /bin/sed -e {s/\m\(.*\)clk" {\.*\n\.*Data\.*//} -i file
exec /bin/sed -e {s/\m\(.*\)clk" {\.*\n\.*P {\.*//} -i file
Could you please try following and let me know if this helps you.(Considering that your actual Input_file is same as shown sample file)
awk -v line_number=$(cat Input_file | wc -l) '/signal {/ || /"o_\[9\]" {/ || FNR==line_number{flag=1}; /^$/{flag=""} flag' Input_file
Explanation: Adding explanation for code too now as follows:
awk -v line_number=$(cat Input_file | wc -l) ' ##Creating variable named line_number in awk script whose value is number of lines of Input_file.
/signal {/ || /"o_\[9\]" {/ || FNR==line_number{ ##checking condition here if a line contains strings either signal { OR "o_\[9\]" { then do following:
flag=1} ##Setting variable named flag here and setting its value to 1 here.
/^$/{ ##Checking condition here if a line is NULL or BLANK then do following:
flag=""} ##Nullifying the variable flag here.
flag ##awk works on method of condition then actions, so checking if variable flag value is NOT NULL here and not mentioning any action here so by default peint of current line will happen here.
' Input_file ##Metioning the Input_file name here.
Solution with a context-sensitive parser:
use Marpa::R2 qw();
my $input = <<'INPUT';
signal {
{
ab
cd
}
"m_1_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"m_0_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
"m_0_clk" {
Data S Mk {
Active Up;
}
}
"m_1_clk" {
Data S Mk {
Active Up;
}
}
}
INPUT
my $grammar = Marpa::R2::Scanless::G->new({
bless_package => 'Foo',
source => \<<'GRAMMAR',
:default ::= action => [values] bless => ::lhs
lexeme default = action => [ value ] bless => ::name latm => 1
:start ::= blocks
blocks ::= block+
block ::= optionalname [{] contentblocks [}] optionalws
optionalname ::= name | epsilon
contentblocks ::= contentorblock+
contentorblock ::= content | block
name ~ [a-zA-Z0-9_"\x{5b}\x{5d} ]+
content ~ [a-zA-Z0-9;'\s]*
optionalws ~ [\s]*
epsilon ::=
GRAMMAR
});
my $parser = Marpa::R2::Scanless::R->new({grammar => $grammar});
$parser->read(\$input);
my $output;
deleteblocks($parser->value->$*);
print $output;
sub deleteblocks {
my ($v) = #_;
return if ref $v eq 'Foo::block' and $v->[0][0]
and $v->[0][0][0] !~ /signal|"o_\[9\]"/;
if (ref $v) {
deleteblocks($_) for $v->#*;
} else {
$output .= $v || '';
}
}
Output is:
signal {
{
ab
cd
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
}
Whenever somebody just types ! point the snippet runs through all of its commands for some reason I'm trying to find what causes this to happen, so far I cannot find the issue in the code
alias -l sd { return " $+ $scriptdir $+ $$1 $+ " }
on $*:text:/^!(monday|tuesday|wednesday|thursday|friday|saturday|sunday|website|food|touchy|sakura|Bass|bacon|snickers|bot|quiz|quizrules|NYE|NYD|stop|dance|Leta|back|sways|ladies|enters|choice|lounge|hiphop|fault|country|piano|rocks|diva|diva1|hello|sassy|hips|bounces|woot|kiss|pops|wiggle|greets|gotit|phone|next|cheeky|dj|xmas|here|guitar|twist|dj1|facebook|cheeky1|jig|birthday|thanks|chacha|moves|fleshies|aerial|drinks|heifer|dances|tap|chacha1|jam|hairbrush|hairbrush1|hairbrush2|reggae|lmfao|accept|hairbrush3|touch|no|music|tinbot|buffering|fleshie1|brat|2step|twirls|vote|whistle|hohey|scripted|botgurl|shows|phone1|laughs|me|crazy|shares|rani|takes|hour|mj|elvis|profiles|song|sweet|brightie|fire|passenger|lr|)$/Si:#:{
if (!%f) { inc -u6 %f
if ($isfile($sd(timetable.txt))) { .play $+(-t,$regml(1)) # $sd(timetable.txt) 50 }
else { msg # Either timetable.txt doesn't exist or the txt file name doesn't match! }
}
}
menu * {
Ping-Pong:$iif(%pp,pingpongoff,pingpongon)
Anti-Idle:$iif(%antiidle,antioff,antion)
}
on 1:ping: { $iif(%pp,raw pong $1 wannaplaypingpong,) }
on 1:pong: { $iif(%pp,raw ping $1 wannaplaypingpong,) }
alias pingpongoff { unset %pp | echo -a Ping-Pong has been disabled. }
alias pingpongon { set %pp on | echo -a Ping-Pong has been enabled. }
alias antioff { timeridle off | unset %antiidle | echo -a Anti-Idle has been disabled. }
alias antion { .timeridle 0 120 scid -atM1 antiidle | set %antiidle on | echo -a Anti-Idle has been enabled. }
alias antiidle { .msg $status $me }
raw 401:*: {
if (connected isin $1-) && (%antiidle) { echo -s ***** SassIRC Anti-Idle | halt }
}
}
}
You have an error at the end of your regex.
...fire|passenger|lr|)$..
Which contain redundant last pipe |, remove it from the end and it will solve the problem.