Best way to divide in bash using pipes?
Using bc
:
$ bc -l <<< "scale=2;$(find . -name '*.mp4' | wc -l)/3"
2.33
In contrast, the bash shell only performs integer arithmetic.
Awk is also very powerful:
$ find . -name '*.mp4' | wc -l | awk '{print $1/3}'
2.33333
You don't even need wc
if using awk
:
$ find . -name '*.mp4' | awk 'END {print NR/3}'
2.33333
BASH: how to perform arithmetic on numbers in a pipe
echo 1 2 3 4 5|{
read line;
for i in $line;
do
echo -n "$((i * i)) ";
done;
echo
}
The {} creates a grouping. You could instead create a script for that.
Divide output of wc-l by 4 in a for loop in bash?
You never use for i in $(ls anything)
, see Bash Pitfalls #1. Your loop will fail for filenames with spaces or any other special characters. For most circumstances, you simply iterate over the files with for i in path/*; do ...
, but understand that can fail if the filenames contain the '\n'
character as part of the name. The optimal for handling all filenames is to use find
as while read -r name; do ... done < <(find path -type f -name "*.gz")
(note process substitution, < <(...)
is a bash only construct, pipe to the loop if using POSIX shell)
Next, to write the name and number of lines / 4 to a new file, wrap your entire loop in a new scope between { .... }
and simply redirect all output at once to the new file.
You should also add validations to check if the file is a directory ending in gz
and skip any found, as well as skipping any empty file (zero file size)
If you it altogether, you could do something like:
{
for i in R1/*.gz; do
[ -d "$i" ] && continue ## skip any directories
[ -s "$1" ] && continue ## skip empty files
nlines=$(gzcat "$i" | wc -l) ## get number of lines
printf "%s\t%s\n" "$i" $((nlines / 4)) ## output name, nlines / 4
done
} > newfile ## redirect all output to newfile
(output is written with a tab
character "\t"
separating the name and number / 4 -- adjust as desired)
Look things over and let me know if you have any questions.
use shell pipe output as calculator input
As mentioned by Charles that parsing ls
is not a good practice but anyway if you want to do that, you can try
ls *.gz |wc -l | xargs echo "0.5*" | bc
Division in bash script
I think the pipe is the problem try something like this:
PorcUsado=$(echo "scale=2;$UsadoMem/$TotalMem" | bc -l)
i haven't tested it yet but you have to echo the string and pipe the result from echo
to bc
.
EDIT: Correcting the variable names
Split output of command by columns using Bash?
One easy way is to add a pass of tr
to squeeze any repeated field separators out:
$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4
Floating point results in Bash integer division
Just double-quote ("
) the expression:
echo "$a / ( $b - 34 )" | bc -l
Then bash will expand the $
variables and ignore everything else and bc
will see an expression with parentheses:
$ a=22
$ b=7
$ echo "$a / ( $b - 34 )"
22 / ( 7 - 34 )
$ echo "$a / ( $b - 34 )" | bc -l
-.81481481481481481481
How do I split a string on a delimiter in Bash?
You can set the internal field separator (IFS) variable, and then let it parse into an array. When this happens in a command, then the assignment to IFS
only takes place to that single command's environment (to read
). It then parses the input according to the IFS
variable value into an array, which we can then iterate over.
This example will parse one line of items separated by ;
, pushing it into an array:
IFS=';' read -ra ADDR <<< "$IN"
for i in "${ADDR[@]}"; do
# process "$i"
done
This other example is for processing the whole content of $IN
, each time one line of input separated by ;
:
while IFS=';' read -ra ADDR; do
for i in "${ADDR[@]}"; do
# process "$i"
done
done <<< "$IN"
How do I use floating-point arithmetic in bash?
You can't. bash only does integers; you must delegate to a tool such as bc
.
Related Topics
How to Get Hostname from Ip (Linux)
Adding Any Current Directory './' to the Search Path in Linux
Trying to Use Bash on Windows and Got No Installed Distributions Message
How to Run Nohup and Write Its Pid File in a Single Bash Statement
How to Install Chkconfig on Ubuntu
Is Usb Supported on Bash on Ubuntu on Windows 10
Indenting Multi-Line Output in a Shell Script
How to Schedule Tcpdump to Run for a Specific Period of Time
Display Only Files and Folders That Are Symbolic Links in Tcsh or Bash
New to Linux Kernel/Driver Development
How to Diff a Directory for Only Files of a Specific Type
How to Conveniently Sync a File Between Two Git Repositories
Listing All User-Installed Packages in Debian
When a Parent Process Is Killed by "Kill -9", Will Subprocess Also Be Killed