Best Way to Divide in Bash Using Pipes

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



Leave a reply



Submit