If the numbers from 1 to 4321 were written out, how many times would the digit '5' appear? [closed] - linux

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have figured out the answer for this program, however I don't really understand what does backslush means in here.
I tried to remove the backslush, then the program print all of numbers from 1 to 4321, but it did not grep how many times number 5 appear.
When I put backslush, it just show the number how many time number 5 appear.
here is my code:
#!/bin/bash
seq 4321 | \
while read -n1 digit; do
echo $digit
done | grep -c 5

You can do
$ seq 4321 | tr -Cd 5 | wc -c
1262
which deletes all the chars but 5 and count the result

Usually back slashes when they are put after a command then it means we are telling program that line still continuing and should be considered as a same line commands execution. Usually we do so to make program cleaner(in the way one shouldn't see a LONG line which is keep continuing and shows like a non readable form).
Coming to your code now:
You need not to use \ after seq command since you are using | and while could be mentioned in new line. Moreover your code is not in a long line so it may not be required and should run without it too.
I tested your code without \ and it worked fine for me.
IMHO you need not to use while loop for this task, you could directly do:
seq 4321 | awk '{sum+=gsub(/5/,"&")} END{print sum}'
Try it out if this helps you(if I have got your requirement correctly), this should be faster than a loop and then using grep option.

With GNU grep you can do like this:
$ seq 4321 | grep -o 5 | wc -l
1262
$
According to grep's manual:
-o, --only-matching
Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.

Related

Find number 9 in file - linux terminal [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I need to find how many times number "9" appears in the result of the draw
(ignoring the ordinal number and date)
65. 11.05.1958 8,17,22,27,31,21
66. 18.05.1958 1,2,8,17,28,54
67. 25.05.1958 7,16,27,33,41,23
68. 01.06.1958 1,20,41,42,43,43
69. 08.06.1952 13,14,25,29,33,47
70. 15.06.1958 17,23,29,39,41,45
71. 22.06.1958 2,14,22,44,48,49
72. 29.06.1958 3,7,13,15,16,47
73. 06.07.1958 10,11,28,38,48,49
74. 13.07.1956 9,16,21,24,27,35
75. 20.07.1958 1,7,17,18,29,32
76. 27.07.1958 19,21,42,25,36,44
77. 03.08.1958 2,4,22,31,32,43
78. 10.08.1958 4,9,16,26,27,46
79. 17.08.1958 34,35,37,38,39,45
80. 24.08.1958 17,21,27,35,41,49
81. 31.08.1958 30,31,32,9,46,49
82. 07.09.1958 10,16,23,26,30,39
83. 14.09.1958 13,16,18,19,30,35
84. 21.09.1958 9,23,26,29,31,42
85. 28.09.1958 12,16,21,28,9,49
Use awk to remove the first 2 columns, then use grep -c to find the 9s. Put a \b around the regex to make sure it doesn't track 19,29,91,92,93,etc. Assuming your output is coming from FILENAME:
awk '{ print $3 }' FILENAME | grep -c '\b9\b
Assuming the text to search is in a file named output.txt:
cut <output.txt -d ' ' -f 3 | grep -w 9 | wc -l
The cut part splits by spaces, taking the third field.
grep -w finds 9 as a word, so the for example the line with 10,16,23,26,30,39 won't get picked.
Finally, wc -l counts how many lines we have.
And just for fun, here is yet another way, this one in Perl:
perl -nle '$c+=()=/\b(9)\b/g; END {print $c}' $FILENAME
This has the difference that it allows 9 to appear multiple times, and counts them all. Because it uses /g (global) and first casts the result to an array ()=, before adding the number of elements in the array to $c.

how to grep a string from a particular line? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to search for a String by navigating to a particular line, How to do this in shell scripting?
For example,
I have
this is the first line
this is the Second line
This is the Third line
Now here i would want to look for string "Third" by going to 3rd line.
Any help is appreciated, Thank you.
Try stringing together cat, sed, and grep.
sed '3!d' filename | grep Third
The unnamed or anonymous pipe (|) and redirection (<, >) are powerful features of many shells. They allow one to combine a set of commands to perform a more complex function.
In the case of this question there were two clear steps,
1) Operate on a specific line of a file (e.g. filter a file)
2) Search the output of the filter for a specific string
Recognizing that there were two steps is a strong indicator that two commands will need to be combined. Therefore, the problem can be solved by finding a solution to each step and then combining them in to one command with pipes and redirection.
If you know about the Stream Editor (sed), it may come to your mind when thinking about how to accomplish the first step of filtering the file. If not searching for, "linux get a specific line of a file" this OS question comes up high in the search results.
$ cat tmp.txt
this is the first line
this is the Second line
This is the Third. line
$ sed '3!d' tmp.txt
This is the Third. line
Knowing that grep can be search for lines with the string of interest the next challenge is to figure out how to get the output of sed as the input to grep. The pipe (|) solves this problem.
sed '3!d' filename | grep Third
Example output:
$ sed '3!d' tmp.txt | grep Third
This is the Third. line
$
Another powerful concept in shell scripting is the exit status. The grep command will set the exit status to 0 when a match is found and 1 when a match is not found. The shell stores the exit status in a special variable named $? (for bash). Therefore, one could use the exit status to conditionally determine the next step in the shell script. The example below does not implement conditions (like if, else). The example below shows the exit status value using the echo command.
$ sed '3!d' tmp.txt | grep Third
This is the Third. line
$ echo $?
0
$ sed '3!d' tmp.txt | grep third
$ echo $?
1
$

How to grep a line of ps afux filtering by PID [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I just want to know how to grep a line which consists of for example
pid with number 2.
I want to grep the whole line. Also, it is very important to filter only and exactly "2". Because at the moment It filters all the number which have 2 in it.
If you want to get the listing for just one particular PID, the -p option is the best way.
ps -f -p 2
for example
If you want grep to match a string only if it is the whole word, not part of another word, look at the -w flag, which matches words like
$ echo '52' | grep 2
52
$ echo '52' | grep -w 2
$
if you want to match against only a particular field, awk might be a better answer than grep. For example, if we want to check if the second column is exactly 2 we could do
ps -af | awk '$2 == 2 {print}'
You could go for something like this. If you need the details of a process and you know the pid go for this.
ps afux | awk '{if($2==<pid>) print}'

SED Command Replacement [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Suppose I have a file with warnings. Each warning in a new line with an id that has 3 capital letters followed by 3 digits only, should be replaced by its id.
Example:
SIM_WARNING[ANA397]: Node q<159> for vector output signal does not exist
The output should be ANA397 and the rest of line is deleted.
How to do so using sed?
I don't think you need sed for that. A simple grep with --only-matching could do, as in:
grep -E 'SIM_WARNING\[(.)\]' --only-matching
should work for you.
Where:
-E does "enhanced regular expressions. I think we need those for capturing with ( )
then follows the pattern, which consists of the fixed SIM_WARNING, followed by a match inside the square brackets
--only-matching simply makes grep print only matching content
In other words: by using ( match ) you tell grep that you only care about the thing in that match pattern.
for id in $(grep -o "^SIM_WARNING\[[A-Z][A-Z][A-Z][0-9][0-9][0-9]\]" test1.bla | grep -o "[A-Z][A-Z][A-Z][0-9][0-9][0-9]" test1.bla ); do echo $id; done
This finds ANA397 from the below.
SIM_WARNING[ANA397]: Node q<159> for vector output signal does not exist
First of all, you have to choose how to use the IDs, for example if you need to cycle the file first or the IDs later...
E.G. (Cycle file first)
exec 3<file
while read -r line <&3; do
id="$(printf "%s" "${line}" | sed -e "s/.*\[\([[:alnum:]]\+\)\].*/\1/")"
### Do something with id
done
exec 3>&-
Otherwise you can decide to cycle the output of sed...
E.G.
for id in $(sed -e "s/.*\[\([[:alnum:]]\+\)\].*/\1/" file); do
### Do something with id
done
Both of the examples should work with posix shell (If I am not missing something...), but shell like posh may not support classes as [[:alnum:]], you can substitute them with the equivalent [a-zA-Z0-9], as every guide will teach you.
Note that the check is not on 3 letters and 3 digits, but for any letter and digit between brackets ([ and ]).
EDIT:
If your lines start with SIM_WARNING you can discriminates those lines with -e "/^SIM_WARNING/! d"
For a strict check on 3 letters and 3 digits you can use -e "s/.*\[\([a-zA-Z][a-zA-Z][a-zA-Z][0-9][0-9][0-9]\)\].*/\1/"
So taking the example above you can do somethin like:
for id in $(sed -e "/^SIM_WARNING/! d" -e "s/.*\[\([a-zA-Z][a-zA-Z][a-zA-Z][0-9][0-9][0-9]\)\].*/\1/" file)
### Do something with id
done

Remove lines in text file which contain fewer than 4 pipes [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
I have a text file with data separated by 4 separate |
There are some problem lines in the file. These lines contain fewer than 4 pipes.
The data in the problem rows is not needed and I want to run a command on the file which deletes any line which contains fewer than four pipes. I would also like to know how many lines were deleted afterwards so if this could be printed on the screen once the command is applied that would be ideal.
Sample data:
865|Blue Moon Club|Havana Project|34d|879
899|Soya Plates|Dimsby|78a|699
657|Sherlock
900|Forestry Commission|Eden Project|68d|864
Desired output:
865|Blue Moon Club|Havana Project|34d|879
899|Soya Plates|Dimsby|78a|699
900|Forestry Commission|Eden Project|68d|864
I have tried awk '|>=3' file.txt which didn't work. There is a lot of info out there regarding awk, some of which I found, but there's so much it makes it difficult to find exactly what I want to do due to its sheer volume.
To eliminate the lines:
grep '|.*|.*|.*|' file > newfile
To count the number of bad lines:
grep -cv '|.*|.*|.*|' file
That doesn't do the edit in place; you could do that with sed but it is often safer to do edits like this to a newfile, in order to avoid losing data if you make a mistake.
The first grep pattern matches any line with four pipe symbols. (By default, grep uses "Basic" regular expressions, in which you have to write the alternation operator \|. So you can use | as an ordinary character.)
The second invocation counts (-c) the number of non-matching (-v) lines.
Here's a simple sed solution:
sed -n -i.bak '/|.*|.*|.*|/p' file
The -n option turns off automatic printing, so the command only prints the lines which match the pattern. (Again, by default, sed uses basic regexes.). The -i.bak option does the edit in place, creating a backup of the original with the name file.bak.
If you wanted to select lines with exactly four pipes, you could use awk:
awk -F'|' 'NF==5' file > newfile
which will set the filed separator to a pipe symbol and then select the lines with exactly five fields, which are the lines with four pipes.
A useful tool to count lines is wc:
wc -l file
will tell you how many lines are in file; if you count lines in both file and newfile, the difference will obviously be the number of deletions. You could do that computation in awk, too, but it's a bit wordier:
awk -F'|' 'NF==5{print;next}{del+=1}END{print del >>"/dev/stderr"}' file > newfile
This will do:
sed -i.bak '/\([^|]*|\)\{4\}/!d' file
Or (as Cyrus's comment)
sed -i.bak -E '/(\|[^\|]*){4}/!d' file
Or
sed -n '/^[^|]*|[^|]*|[^|]*|[^|]*|$/p' file > newfile
Or
sed -e '/^[^|]*|[^|]*|[^|]*|$/d' \
-e '/^[^|]*|[^|]*|$/d' \
-e '/^[^|]*|$/d' \
-e '/^[^|]*$/d' \
-i.bak file
This won't give you line count though. To get line count run grep -cv '^[^|]*|[^|]*|[^|]*|[^|]*|$' file on the original file as rici mentioned, or compare the line number before and after with wc -l file command
Explanation:
The first two sed matches loosely 4 pipes (not less but can be more) and the third one matches exactly 4 | (not more or less).
The fourth sed matches exactly 3,2,1 and 0 pipes (|) and deletes those lines (in place) and prepares a backup file (file.bak) of the original.

Resources