# Tag Info

118

If you know you are dealing with two integers a and b, then these simple shell arithmetic expansions using the ternary operator are sufficient to give the numerical max: \$(( a > b ? a : b )) and numerical min: \$(( a < b ? a : b )) E.g. \$ a=10 \$ b=20 \$ max=\$(( a > b ? a : b )) \$ min=\$(( a < b ? a : b )) \$ echo \$max 20 \$ echo \$min 10 \$ a=30 \$ ...

89

bash In bash, that's probably as good as it gets. That uses a shell builtin. If you need the result in a variable, you could use command substitution, or the bash specific (though now also supported by zsh): printf -v int %.0f "\$float" You could do: float=1.23 int=\${float%.*} But that would remove the fractional part instead of giving you the nearest ...

37

I don't know if it is beautiful, but it is working for every version format I know. #!/bin/bash currentver="\$(gcc -dumpversion)" requiredver="5.0.0" if [ "\$(printf '%s\n' "\$requiredver" "\$currentver" | sort -V | head -n1)" = "\$requiredver" ]; then echo "Greater than or equal to \${...

32

The leading 0 causes Bash to interpret the value as an octal value; 012 octal is 10 decimal, so you get 11. To force the use of decimal, add 10# (as long as the number has no leading sign): BN=10#\$(cat Build.number) echo \$((++BN)) > Build.number To print the number using at least three digits, use printf: printf "%.3d\n" \$((++BN)) > Build.number

30

You can force conversion of a number to a specific base in bash like so: \$ foo=400 \$ echo \$((8#\$foo)) 256 \$ bar=0100 \$ echo \$((10#\$bar)) 100 In general the format is \$((base#value)).

27

bc - An arbitrary precision calculator language int(float) should looks like: \$ echo "\$float/1" | bc 1234 To round better use this: \$ echo "(\$float+0.5)/1" | bc Example: \$ float=1.49 \$ echo "(\$float+0.5)/1" | bc 1 \$ float=1.50 \$ echo "(\$float+0.5)/1" | bc 2

27

The question in the body Select lines that start with a 1 and are followed by an space grep -c '^1\s' file grep -c '^1[[:space:]]' file That will also give the count of lines (without needing the call to wc) The question in the title A 1 not followed by another number (or nothing): grep -cE '^1([^0-9]|\$)' file But both solutions above have ...

26

sort and head can do this: numbers=(1 4 3 5 7 1 10 21 8) printf "%d\n" "\${numbers[@]}" | sort -rn | head -1 # => 21

22

You can compare just two numbers with dc like: dc -e "[\$1]sM \$2d \$1<Mp" ... where "\$1" is your max value and "\$2" is the number you would print if it is lesser than "\$1". That also requires GNU dc - but you can do the same thing portably like: dc <<MAX [\$1]sM \$2d \$1<Mp MAX In both of the above cases you can set the precision to something ...

22

The test command, also named [, has separate operators for string comparisons and integer comparisons: INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2 vs STRING1 = STRING2 the strings are equal and STRING1 != STRING2 the strings are not equal Since your data is not strictly an integer, your test needs to use the string comparison operator. The last ...

22

You can; you just need to break the range {0..F} into two separate ranges {0..9} and {A..F}: \$ printf '%s\n' {{0..9},{A..F}}{{0..9},{A..F}} 00 01 ... FE EF

19

Sounds like you just want this: \$ grep '^1\b' a 1 TGCAG..... 1 TGCAG...... For the counting portion of this: \$ grep -c '^1\b' file 2

18

If your grep support -o option, you can try: \$ grep -o '[[:digit:]]*' file | paste -sd+ - | bc 784 POSIXly: \$ printf %d\\n "\$(( \$(tr -cs 0-9 '[\n*]' <file | paste -sd+ -) ))" 784

18

bash treats constants that start with 0 as octal numbers in its arithmetic expressions, so 011 is actually 9. That's actually a POSIX requirement. Some other shells like mksh or zsh ignore it (unless in POSIX compliant mode) as it gets in the way far more often than it is useful. With ksh93, BN=011; echo "\$((\$BN))" outputs 9, but echo "\$((BN))" outputs 11....

16

With a newer version (4.x) of GNU awk: awk 'BEGIN {FPAT="[0-9]+"}{s+=\$1}END{print s}' With other awks try: awk -F '[a-z=]*' '{s+=\$2}END{print s}'

16

With awk: awk '\$1 == "1" { print; x++ } END { print x, "total matches" }' inputfile

15

Using printf: \$ printf '%.2x\n' {0..255} The format string %.2x says to format the output as a zero-filled, two-digit, lower-case, hexadecimal number (%02x would have done the same). If you want upper-case, use %.2X. Bash only understands base 10 integer ranges or ranges between ASCII characters in brace expansions of intervals.

14

grep works well for this: \$ echo "2.5 test. test -50.8" | grep -Eo '[+-]?[0-9]+([.][0-9]+)?' 2.5 -50.8 How it works -E Use extended regex. -o Return only the matches, not the context [+-]?[0-9]+([.][0-9]+)?+ Match numbers which are identified as: [+-]? An optional leading sign [0-9]+ One or more numbers ([.][0-9]+)? An optional period followed by ...

14

With gawk (GNU awk) for the asort() function: gawk -v SEP='*' '{ i=0; split(\$0, arr, SEP); len=asort(arr); while ( ++i<=len ){ printf("%s%s", i>1?SEP:"", arr[i]) }; print "" }' infile replace * as the field separator in SEP='*' with your delimiter. You can also do with the following command in case of a ...

14

Either of these will pick out lines with a 1 in the first column awk '\$1 == 1' grep -w '^1' These can both can be extended so you don't even need the wc to count the lines awk '\$1==1 { x++ } END { print x }' grep -cw '^1'

13

You can do this using printf and bash: printf '%08x\n' \$(< test.txt) Or using printf and bc...just...because? printf '%08s\n' \$(bc <<<"obase=16; \$(< test.txt)") In order to print the output to a text file just use the shell redirect > like: printf '%08x\n' \$(< test.txt) > output.txt

13

Along the paste lines, but doing the math with bc: \$ paste -d+ file1 file2 | bc 7 9 11 13 15 The intermediate result (before bc): \$ paste -d+ file1 file2 1+6 2+7 3+8 4+9 5+10 For a more bash-centric solution, and assuming that file2 has at least as many lines as file1: mapfile -t file1 < file1 mapfile -t file2 < file2 for((i=0; i < \${#file1[@]};...

13

Pass the price through tonumber: curl -sS 'https://api.binance.com/api/v1/ticker/price?symbol=BTCUSDT' | jq -r '.price | tonumber' This would convert the price from a string to a number, removing the trailing zeros. See the manual for jq.

12

I think I found this answer in another StackOverflow question, but I found "q" quite useful for that purpose: https://github.com/harelba/q. E.g. your example goal would be achievable like that: \$ q "select c2, sum(c3) from data group by c2" u1 423404 u2 3948 And since it uses sqlite as a backend you can use all sorts of sqlite functions to make ...

12

Using perl there's an obvious version; split the data, sort it, join it back up again. The delimiter needs to be listed twice (once in the split and once in the join) eg for a , perl -lpi -e '\$_=join(",",sort {\$a <=> \$b} split(/,/))' So echo 1,100,330,42 | perl -lpi -e '\$_=join(",",sort {\$a <=> \$b} split(/,/))' 1,42,100,330 Since the split ...

12

You can use paste -s to join lines: shuf -i1-10 | paste -sd, - This uses -i option of shuf to specify a range of positive integers. The output of seq can be piped to shuf: seq 10 | shuf | paste -sd, - Or -e to shuffle arguments: shuf -e {1..10} | paste -sd, -

11

factor {2..1000} | awk 'NF==2{print \$2}'

11

If that list was in a file, one per line, I'd do something like: sort -nu file | awk 'NR == FNR {rank[\$0] = NR; next} {print rank[\$0]}' - file If it was in a zsh \$array: sorted=(\${(nou)array}) for i (\$array) echo \$sorted[(i)\$i] That's the same principle as for the awk version above, the rank is the index NR/(i) in the numerically (-n/(n)) ordered ...

Only top voted, non community-wiki answers of a minimum length are eligible