I have the following sample strings:
Program exiting with code: 0.
Program exiting with code: 1.
Program exiting with code: 10.
I want grep to return values after the matching pattern "Program exiting with code:". However I do not need the period at the end. I have tried:
grep "Program exiting with exit code:" dataload.log | sed 's/^.*.: //'
The above command returns:
0.
1.
10.
I want to ignore the period at end. I picked up the above command from somewhere.
Can someone describe what each keyword represents and provide me with a regex that will only provide me with the value without period?
sed, awk, perl or any other way is fine with me.
Just use grep with a look-behind and catch only digits:
$ grep -Po '(?<=Program exiting with code: )\d*' file
0
1
10
sed 's/^.*.: //'
First of all this is a substition regular expression, as denoted by the s at the start. The part in the first / / is what to match and the second / / is what to replace it with.
The characters in the first (match) part of the expression are all special regular expression characters.
A full list of what they mean can be found here: http://www.rexegg.com/regex-quickstart.html
The match means:
^ - At the start of the line
. - Match any character
* - Any number of times
. - Match any character
: - Match a colon
- Match a space
And then that is all replaced with nothing. That is why the period at the end is kept because it removes everything up to Program exiting with code:, which leaves 1.
It's worth playing around with an interactive tool to test different regular expressions on your string, e.g. http://www.regexr.com/
You can probably just substitute/remove everything that is not a number in your case: 's/[^0-9]//g'.
This is another way:
grep -oE 'Program exiting with code:\s*[0-9]+' dataload.log |grep -oE '[0-9]+$'
Output of the first grep command is:
Program exiting with code: 0
Program exiting with code: 1
Program exiting with code: 10
Then you just grep the last digits.
Your solution is just fine if you extend it with a cut command:
grep "Program exiting with code:" dataload.log | sed 's/^.*.: //' | cut -d"." -f1
Related
Please help resolving the below syntex error thrown from Ansible:
ERROR! Syntax Error while loading YAML. mapping values are not
allowed in this context
The error appears to be in
'/app/iap_workspace/portals/workpro/dev/sanity/ansible/system/log_check.yml':
Line 244, column 45
But may
be elsewhere in the file depending on the exact syntax problem.
The lines that appear wrong are these:
- name: load average
raw: uptime | sed 's/.*load average: //' | awk -F\, '{print $3}'| bc | nawk -v thres=2.0 '{if($1 < thres) print "GOOD"; else print "BAD";}'
^ here
I could be wrong but this one looks like it might be an issue with
unbalanced quotes.
If starting a value with a quote, make sure the
line ends with the same set of quotes.
For instance this arbitrary
example:
foo: "bad" "wolf"
Could be written as:
foo: '"bad" "wolf"'
The executable command is uptime | sed 's/.*load average://' | awk -F\, '{print $3}'
No space after load average:
If you put space after ":" ansible will take as a part of its own syntax like how we are staring to use any attributes for ansible.
For example-
raw:(space) (your command).
This command is not throwing "bad" with any threshold value. Moreover, we want load average equal to 15mins, meaning the 3rd value. Something I can see is that the last value position is not the fixed one. So can you give a command where we can get the 3rd value by differentiating the strings by s/.*load average?
Like this:
uptime | sed 's/.*load average: //' | awk -F\, '{print $3}'
How to remove line if characters do not exist after a symbol (e.g. #)?
E.g.
hello#lawyer
B#b
smith#
Nac#gyo
treat#
Lines smith# and treat# will be removed as there are no characters after #.
I would post sample of my experimentation -- but have been so far off the mark that would be unhelpful.
using the delete command d and the $ anchor that matches the end of the line:
sed '/#$/d' file
/#$/: when this pattern succeeds, the d command is executed.
You could use grep -v:
grep -v '#$'
to exclude all lines that match the pattern "line ends with #".
I am trying to use a sed command to replace specials characters in my file.
The characters are %> to replace by ].
I'am using sed -r s/\%>\/\]\/g but i have this error bash: /]/g: No such file or directory, looks like sed doesn't like it.
Put your sed code inside quotes and also add the file-path you want to work with and finally don't escape the sed delimiters.
$ echo '%>' | sed 's/%>/]/g'
]
ie,
sed 's/%>/]/g' file
To complement Avinash Raj's correct and helpful answer:
Since you were using an overall unquoted string (neither single- nor double-quoted), you were on the right track by \-escaping individual characters in your sed command.
However, you neglected to \-quote >, which is what caused your problem:
> is one of the shell's so-called metacharacters
Metacharacters have special meaning and separate words
Thus, s/\%>\/\]\/g is mistakenly split into 2 arguments by >:
s/\% is passed to sed - as s/%, because the shell removes the \ instances (a process called quote removal).
As you can see, this is not a valid sed command, but that doesn't even come into play - see below.
>\/\]\/g is interpreted by the shell (bash), because it starts with output-redirection operator >; after quote removal, the shell sees >/]/g, tries to open file /]/g for writing, and fails, because your system doesn't have a subdirectory named ] in its root directory.
bash tries to open an output file specified by a redirection before running the command and, if it fails to open the file, does not run the command - which is what happened here:
bash complained about the nonexistent target directory and aborted processing of the command - sed was never even invoked.
Upshot:
In a string that is neither enclosed in single nor in double-quotes, you must \-quote:
all metacharacters: | & ; ( ) < > space tab
additionally, to prevent accidental pathname expansion (globbing): * ? [
Also note that if you need to quote (escape) characters for sed,you need to add an extra layer of quoting; for instance to instruct sed to use a literal . in the regex, you must pass \\. - two backslashes - so that sed sees the properly escaped \..
Given the above, it is much simpler to (habitually) use single quotes around your sed command, because it ensures that the string is passed as is to sed.
Let's compare a working version of your command to the one from Avinash Raj's answer (leaving out the -r for brevity):
sed s/\%\>\/\]\/g # ok - all metachars. \-quoted, others are, but needn't be quoted
sed s/%\>/]/g # ok - minimum \-quoting
sed 's/%>/]/g' # simplest: single-quoted command
I'm not sure whether I got the question correctly. If you want to replace either % or > by ] then sed is not required here. Use tr in this case:
tr '%>' ']' < input.txt
If you want to replace the sequence %> by ] then the sed command as shown by #AvinashRaj is the way to go.
Basically, I want to add the filter to the output of my perl script. This filter would chop the redundant lines matching the pattern , 'Jobs found shutdown' and would result in the clean output. Now what and where should I use grep or sed to implement this approach?? And this filter should be the part of the script which would help in getting the clean output.
I am planning to use below sed command to match the lines and remove them from the console output. But need help in implementation
have the script which has some redundant lines from the server in its output.At the end of the script , I would be running the following sed command to clear the output of the script at the console.
"sed -i '/No Job found./d' ";
I think grep is your friend in this case. Something along the lines
perl ... | grep -v "No Job found"
Will result in only lines not containing No Job found being printed
I couldn't find an answer for this exact problem, so I'll ask it.
I'm working in Cygwin and want to reference previous commands using !n notation, e.g., if command 5 was which ls, then !5 runs the same command.
The problem is when trying to do substitution, so running:
!5:s/which \([a-z]\)/\1/
should just run ls, or whatever the argument was for which for command number 5.
I've tried several ways of doing this kind of substitution and get the same error:
bash: :s/which \([a-z]*\)/\1/: substitution failed
As far as I can tell the s/old/new/ history substitution syntax only does simple string substitution; it does not support full regexes. Here's what man bash has to say:
s/old/new/
Substitute new for the first occurrence of old in the event line. Any delimiter can be used in place of /. The final delimiter is optional if it is the last character of the event line. The delimiter may be quoted in old and new with a single backslash. If & appears in new, it is replaced by old. A single backslash will quote the &. If old is null, it is set to the last old substituted, or, if no previous history substitutions took place, the last string in a !?string[?] search.
Never fear, though. There are in fact easier ways to accomplish what you are trying to do:
!$ evaluates to the last argument of the previous command:
# ls /etc/passwd
/etc/passwd
# vim !$
vim /etc/passwd
!5:$ evaluates to the last argument of command #5:
# history
...
5: which ls
...
# !5:$
ls
You can also use Alt+. to perform an immediate substitution equivalent to !$. Alt+. is one of the best bash tricks I know.
This worked for me using Bash in Cygwin (note that my which ls command was number 501 in my history list; not 5 like yours):
$(!501 | sed 's/which \([a-z]\)/\1/')
You could also do it this way (which is shorter/cleaner):
$(!501 | sed 's/which //')