Bash Shell Commands with options - linux

I'm having issues with piping the translate command into the word count command using the shell for an assignment. Using Debian 9 Linux distro.
I need to remove colons from the passwd file in the /etc directory and pipe the results into "word count" or wc -w. I have read the man pages, google searched and tried youtube videos, but could not find anything that would point me in the right direction. Things I have tried include:
tr -d ":" | wc -w /etc/passwd
tr -d [:punct:] | wc -w /etc/passwd
tr -- delete [:punct:] | wc -w /etc/passwd
tr -s [:punct:] [:space:] | wc -w /etc/passwd
tr -t [:] [" "] | wc -w /etc/passwd
The piped command is supposed to delete colons, replace them with spaces, and change the word count/"wc" commands output.
Before using translate and piping to wc, passwd's word count is equal to 37 lines, 60 words and 2054 bytes. I believe the number is supposed to increase when you remove the colons.

You have to send the content of the file to tr first.
< /etc/passwd tr ":" " " | wc -w
Or with cat, even when it's a useless use of cat.
cat /etc/passwd | tr ":" " " | wc -w

you mean something like this?
tr ":" " " < /etc/passwd | wc -w

Related

grep a character/word from a string and count number of occurrences in Linux

I like to a grep a character from a string then count it, I don't see from google search. Please advise. I might miss search for it.
node_count=`echo "test1|test2|test3" | grep "|" |wc -l`|echo $node_count
output is always 1 to me.
1
Remember that I don't grep from a file but a line of string. Grep from a file is easy.
You might want to use option -o of grep:
$ node_count=`echo "test1|test2|test3" | grep "|" -o |wc -l` && echo $node_count
# 2

Need to cut part of a string in shell scripting

I have a string example.123.ytu.tar.gz
I want to have example.123.ytu.tar how can i get in shell scripting
I tried with
echo example.123.ytu.tar | cut -d "." -f3, But it is giving only tar
I would use basename for this.
$ basename --suffix ".gz" example.123.ytu.tar.gz
example.123.ytu.tar
You can find out more about it via man basename
echo example.123.ytu.tar.gz | cut -d "." -f1-4
example.123.ytu.tar
The -f option takes any comma separated list of fields and/or field ranges (with '-'). Eg
echo example.123.ytu.tar.gz | cut -d "." -f1,2,3,4
example.123.ytu.tar
gives the same output.
You could simply use grep
echo example.123.ytu.tar | grep -Eo '.*tar'
output: example.123.ytu.tar
The -E option enables extended regular expression mode and the -o option makes grep print only the part of the word that matched the regex.

Bash grep output filename and line no without matches

I need to get a list of matches with grep including filename and line number but without the match string
I know that grep -Hl will give only file names and grep -Hno will give filename with only matching string. But those not ideal for me. I need to get a list without match but with line no. For this grep -Hln doesn't work. I tried with grep -Hn 'pattern' | cut -d " " -f 1 But it doesn't cut the filename and line no properly.
awk can do that in single command:
awk '/pattern/ {print FILENAME ":" NR}' *.txt
You were pointing it well with cut, only that you need the : field separator. Also, I think you need the first and second group. Hence, use:
grep -Hn 'pattern' files* | cut -d: -f1,2
Sample
$ grep -Hn a a*
a:3:are
a:10:bar
a:11:that
a23:1:hiya
$ grep -Hn a a* | cut -d: -f1,2
a:3
a:10
a:11
a23:1
I guess you want this, just line numbers:
grep -nh PATTERN /path/to/file | cut -d: -f1
example output:
12
23
234
...
Unfortunately you'll need to use cut here. There is no way to do it with pure grep.
Try
grep -RHn Studio 'pattern' | awk -F: '{print $1 , ":", $2}'

Why bc and args doesn't work together in one line?

I need help using xargs(1) and bc(1) in the same line. I can do it multiple lines, but I really want to find a solution in one line.
Here is the problem: The following line will print the size of a file.txt
ls -l file.txt | cut -d" " -f5
And, the following line will print 1450 (which is obviously 1500 - 50)
echo '1500-50' | bc
Trying to add those two together, I do this:
ls -l file.txt | cut -d" " -f5 | xargs -0 -I {} echo '{}-50' | bc
The problem is, it's not working! :)
I know that xargs is probably not the right command to use, but it's the only command I can find who can let me decide where to put the argument I get from the pipe.
This is not the first time I'm having issues with this kind of problem. It will be much of a help..
Thanks
If you do
ls -l file.txt | cut -d" " -f5 | xargs -0 -I {} echo '{}-50'
you will see this output:
23
-50
This means, that bc does not see a complete expression.
Just use -n 1 instead of -0:
ls -l file.txt | cut -d" " -f5 | xargs -n 1 -I {} echo '{}-50'
and you get
23-50
which bc will process happily:
ls -l file.txt | cut -d" " -f5 | xargs -n 1 -I {} echo '{}-50' | bc
-27
So your basic problem is, that -0 expects not lines but \0 terminated strings. And hence the newline(s) of the previous commands in the pipe garble the expression of bc.
This might work for you:
ls -l file.txt | cut -d" " -f5 | sed 's/.*/&-50/' | bc
Infact you could remove the cut:
ls -l file.txt | sed -r 's/^(\S+\s+){4}(\S+).*/\2-50/' | bc
Or use awk:
ls -l file.txt | awk '{print $5-50}'
Parsing output from the ls command is not the best idea. (really).
you can use many other solutions, like:
find . -name file.txt -printf "%s\n"
or
stat -c %s file.txt
or
wc -c <file.txt
and can use bash arithmetics, for avoid unnecessary slow process forks, like:
find . -type f -print0 | while IFS= read -r -d '' name
do
size=$(wc -c <$name)
s50=$(( $size - 50 ))
echo "the file=$name= size:$size minus 50 is: $s50"
done
Here is another solution, which only use one external command: stat:
file_size=$(stat -c "%s" file.txt) # Get the file size
let file_size=file_size-50 # Subtract 50
If you really want to combine them into one line:
let file_size=$(stat -c "%s" file.txt)-50
The stat command gets you the file size in bytes. The syntax above is for Linux (I tested against Ubuntu). On the Mac the syntax is a little different:
let file_size=$(stat -f "%z" mini.csv)-50

egrep: find lines with no characters

I have a text file and I need to search that file and figure how many blank lines are in the file. A blank line is a line with no characters.
I must use egrep.
[aman#localhost ~]$ cat >try
sldjjsd
dkfjkjdf
dfkjdf
[aman#localhost ~]$ egrep '^$' try|wc -l
4
This will do.
egrep '^$' blankfile -c
Another way, without egrep.
echo $(($(cat blank | wc -l)-$(cat blank | tr -s "\n" | wc -l)))

Resources