how to same the output value to respective variables [duplicate] - bash

This question already has answers here:
How do I set a variable to the output of a command in Bash?
(15 answers)
Closed 4 years ago.
the variables line,word,char dont get value!
line= wc -l < $*
word= wc -w < $*
char= wc -m < $*
echo "Number of characters in test.txt is $char"
echo "Number of words in test.txt is $word"
echo "Number of lines in test.txt is $line"

You have to wrap the command in $():
line=$(wc -l < $1)

Related

How to use multiple variable in for loop in sh? [duplicate]

This question already has answers here:
How do I pipe a file line by line into multiple read variables?
(3 answers)
Closed 18 days ago.
I want to use multiple variable in for loop at once in sh.
I have a query like this:
top -n 1 -b -c| awk -vOFS="\t" '{print $1,$2,$9}'
I know i use for loop in bash like this:
for i in {2..10}
do
echo "output: $i"
done
what i want to try is:
for x y z in $(top -n 1 -b -c| awk -vOFS="\t" {print $1,$2,$9}')
do
echo "output: $x $y $z"
done
Pipe to a while read loop:
top -n 1 -b -c| awk -vOFS="\t" '{print $1,$2,$9}' | while IFS=$'\t' read -r x y z
do
echo "output: $x $y $z"
done

How to read line by line from file, count specific character [duplicate]

This question already has answers here:
Count occurrences of a char in a string using Bash
(9 answers)
Closed 3 years ago.
I have a data in file.txt like below
N4*1
NM1*IL*2
PER*IC*XM*
how can i read line by line and get the character * count ?
Pseudocode
#!bash/sh
cd `dirname $0`
filelinecount=echo '$(wc -l file.txt)'
if [ $filelinecount -gt 0 ] ; then
for (int i=0, i++); do
fileline=$i (STORES LINE IN VARIABLE)
charactercount= cat '$fileline | wc [*] $fileline'
(GET CHARACTER [*] COUNT AND STORED IN VARIABLE)
echo $charactercount
done
else
echo "file.txt don't contain any lines"
fi
Expected output:
'For' Loop should read line by line from file and store each line in variable "fileline" then count the characters [*] and store in variable "charactercount" then print the variable $charactercount. This loop has to repeat for for all the files in the file. How can i achieve this in 'for' loop ?
1
2
3
This is not a duplicate question as this question clearly asked count of characters using "for" loop.
"Count occurrences of a char in a string using Bash" post don't have answer to this post
awk '{print gsub(/\*/,$0)}' file
To achieve the same in a loop:
#! /bin/bash
while read line
do
grep -o '*' <<<"$line" | grep -c .
done < file
This should print * count per line.
Update as per the comment:
#! /bin/bash
while read line
do
echo "$line" | awk -F"[*]" '{print NF-1}'
done < file
[ ! -s file ] && echo "no lines in file"
[ ! -s file ] has nothing to do with loop. -s flag checks if file has contents. If it has t returns true. But in your case you want opposite behaviour so we used !. So when file is empty, it returns true and && causes the next command to execute i.e. echo "no lines in file”.
tr -d -c '*\n' file.txt | awk '{print length}'
Remove everything except stars and newlines from the file. Then print the line lengths.

Replacing part of a string in bash using sed [duplicate]

This question already has answers here:
unix sed substitute nth occurence misfunction?
(3 answers)
Closed 4 years ago.
In bash, suppose I have the input:
ATGTGSDTST
and I want to print:
AT
ATGT
ATGTGSDT
ATGTGSDTST
which means that I need to look for all the substrings that end with 'T' and print them.
I thought I should use sed inside a for loop, but I don't understand how to use sed correctly in this case.
Any help?
Thanks
The following script uses sed:
#!/usr/bin/env bash
pattern="ATGTGSDTST"
sub="T"
# Get number of T in $pattern:
num=$(grep -o -n "T" <<< "$pattern" | cut -d: -f1 | uniq -c | grep -o "[0-9]\+ ")
i=1
text=$(sed -n "s/T.*/T/p" <<< "$pattern")
echo $text
while [ $i -lt $num ]; do
text=$(sed -n "s/\($sub[^T]\+T\).*/\1/p" <<< "$pattern")
sub=$text
echo $text
((i++))
done
gives output:
AT
ATGT
ATGTGSDT
ATGTGSDTST
No sed needed, just use parameter expansion:
#! /bin/bash
string=ATGTGSDTST
length=${#string}
prefix=''
while (( ${#prefix} != $length )) ; do
sub=${string%%T*}
sub+=T
echo $prefix$sub
string=${string#$sub}
prefix+=$sub
done

Bash for loop stops after one iteration without error [duplicate]

This question already has answers here:
What does set -e mean in a bash script?
(10 answers)
Closed 2 years ago.
Lets say I have a file dates.json:
2015-11-01T12:01:52
2015-11-03T03:58:57
2015-11-09T02:43:59
2015-11-10T08:22:00
2015-11-11T05:14:51
2015-11-11T12:47:02
2015-11-13T08:33:40
I want to separate the rows to different files according to the date.
I made the following script:
#!/bin/bash
set -e
file="$1"
for i in $(seq 1 1 31); do
if [ $i -lt 10 ]; then
echo 'looking for 2015-11-0'$i
cat $file | grep "2015-11-0"$i > $i.json
else
echo 'looking for 2015-11-'$i
cat $file | grep "2015-11-"$i > $i.json
fi
done
When I execute I get the following:
$ bash example.sh dates.json
looking for 2015-11-01
looking for 2015-11-02
If I try without the cat... rows the script prints all the echo commands, and if I try only the cat | grep command on the command line it works.
Would you know why does it behave like this?
If you need set -e in other parts of the script, you need to handle grep not to stop your script:
# cat $file | grep "2015-11-0"$i > $i.json
grep "2015-11-0"$i "$file" > $i.json || :
set -e forces script to exit if command exits with non-zero status.
+
grep returns 1 if it fails to find match in file.
+
dates.json has no 2015-11-02
=
error
it's because of our set -e which causes the script to exit. Remove this line, then it should work

shell bash - How to split a string acoring to a delimeter and echo each substring to a file [duplicate]

This question already has answers here:
How do I split a string on a delimiter in Bash?
(37 answers)
Closed 9 years ago.
Hi I am trying to split a string am getting from a file, using the delimiter "<" I then want to echo each string to a file. I am sort of there, but am not sure how to best split the string and then loop echo each substring (there may be up to 10 substrings) I am guessing I need to create an array to store these strings and then have a loop to echo each value?
Here is what I have so far:
while read line
do
# ceck if the line begins with client_values=
if[["$line" == *client_values=*]]
CLIENT_VALUES = 'echo "${line}" | cut -d'=' -f 2'
#Now need to split the CLIENT_VALUES using "<" as a delimeter.
# for each substring
echo "Output" >> ${FILE}
echo "Value $substring" >> ${FILE}
echo "End" >> ${FILE}
done < ${PROP_FILE}
grep '^client_values=' < "${PROP_FILE}" | while IFS='=' read name value
do
IFS='<' read -ra parts <<< "$value"
for part in "${parts[#]}"
do
echo "Output"
echo "Value $part"
echo "End"
done >> "${FILE}"
done
One line awk might be simpler here (and you get the added bonus of having the angry face regex separator =<)
$ awk -F "[=<]" '/^client_values/ { print "Output"; for (i = 2; i <= NF; i++) print "Value " $i; print "End"}' input.txt >> output.txt
$ cat input.txt
client_values=firstvalue1<secondvalue2<thirdvalue3
some text
client_values=someothervalue1<someothervalue2
$ cat output.txt
Output
Value firstvalue1
Value secondvalue2
Value thirdvalue3
End
Output
Value someothervalue1
Value someothervalue2
End
Your answer could probably also work, I think with minimal modification, you would want something like
#!/bin/bash
PROP_FILE='input.txt'
FILE="output2.txt"
while read line
do
# ceck if the line begins with client_values=
if [[ "$line" == "client_values="* ]]
then
CLIENT_VALUES=`echo "${line}" | cut -d'=' -f 2`
IFS='<' read -ra CLIENT_VALUES <<< "$CLIENT_VALUES"
for substring in "${CLIENT_VALUES[#]}"; do
echo "Output" >> "${FILE}"
echo "Value $substring" >> "${FILE}"
echo "End" >> "${FILE}"
done
fi
done < "${PROP_FILE}"
Which produces
$ cat output2.txt
Output
Value firstvalue1
End
Output
Value secondvalue2
End
Output
Value thirdvalue3
End
Output
Value someothervalue1
End
Output
Value someothervalue2
End
Though again, not sure if that's what you want or not.

Resources