Shell Bash script to print numbers in ascending order
You can use this script:
#!/bin/bash
IFS=' ' read -ra arr -p "Enter numbers: "
Enter numbers: 4 -1 2 66 10
sort -n <(printf "%s\n" "${arr[@]}")
-1
2
4
10
66
IFS=' '
to makeread
all number delimited by space- 'read -ra` to read all numbers in an array
sort -n
to sort numbers numericallyprintf "%s\n" "${arr[@]}"
to print each element of array in separate line<(printf "%s\n" "${arr[@]}")
is process substitution that make itprintf
command behave like a file forsort -n
command.
sorting an output in numeric order bash
Using GNU awk:
awk 'NR==1 { print;next } { split($4,map,":");map1[map[1]][map[2]][map[3]]=$0} END { PROCINFO["sorted_in"]="@ind_num_asc";for ( i in map1 ) { for ( j in map1[i]) { for ( k in map1[i][j]) { print map1[i][j][k] } } } }' file
Explanation:
awk 'NR==1 {
print; # For the first line ( headers) print and skip to the next line
next
}
{ split($4,map,":"); # Split the fourth space separated field into the array map using ":" as the delimiter
map1[map[1]][map[2]][map[3]]=$0 # Create a 3 dimensional array called map with the first, second and third indexes of map as the indexes and the line as the value
}
END {
PROCINFO["sorted_in"]="@ind_num_asc"; # Set the array ordering (index number ascending)
for ( i in map1 ) {
for ( j in map1[i]) {
for ( k in map1[i][j]) {
print map1[i][j][k] # At the end of processing the file, loop through the map1 array and print the values.
}
}
}
}' file
Sorting numbers in a row on the BASH / Shell
try this;
#!/bin/bash
while read line
do
beforeC=$(echo "$line" | cut -f-5 -d';')
sortcolumn=$(echo "$line" | awk -F ";" '{print $6}' | tr -t , "\n" | sort -r -n | xargs | sed 's/ /,/g')
afterC=$(echo "$line" | cut -f7- -d';')
echo -e $beforeC";"$sortcolumn";"$afterC
done <file
user@host:/tmp/test$ cat file
00000000000000;000022233333;2;NONE;true;100,100,5,1,28;UNKNOWN
00000000000000;000022233333;2;NONE;true;99,100,5,1,28;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,99,5,1,28;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,100,4,1,28;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,100,4,0,28;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,100,4,1,27;UNKNOWN
user@host:/tmp/test$ ./sortAColumn.sh
00000000000000;000022233333;2;NONE;true;100,100,28,5,1;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,99,28,5,1;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,99,28,5,1;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,100,28,4,1;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,100,28,4,0;UNKNOWN
00000000000000;000022233333;2;NONE;true;100,100,27,4,1;UNKNOWN
sort alphanumerically with priority for numbers in linux
So, basically, you're asking to sort the first field numerically in descending order, but if the numeric keys are the same, you want the second field to be ordered in natural, or ascending, order.
I tried a few things, but here's the way I managed to make it work:
sort -nk2 file.txt | sort -snrk1
Explanation:
The first command sorts the whole file using the second, alphanumeric field in natural order, while the second command sorts the output using the first numeric field, shows it in reverse order, and requests that it be a "stable" sort.
-n
is for numeric sort, versus alphanumeric, in which 6 would come before 60.-r
is for reversed order, so from highest to lowest. If unspecified, it will assume natural, or ascending, order.-k
which key, or field, to use for sorting order.-s
for stable ordering. This option maintains the original record order of records that have an equal key.
Bash:: How to sort according to first numeric column of file?
How about this:
sed -e 's/^[^0-9.]*\([0-9.]\+\).*$/\1\t\0/' input | sort -n | cut -f 2-
We extract the first numeric field and we insert it to the beginning of each line. Then we sort numerically all lines and then we remove the stuff that we added in the first step.
shell script to print and sort the date column in csv
It should be sort -t, -nk4
(-
is missing before options).
To output only the 10 first lines, you can pipe your sort
to head
:
sort -t, -nk4 file.csv | head -n10 > /tmp/s.csv
The same maybe a bit more readable:
sort -t "," -k 4 -n file.csv | head -n10 > /tmp/s.csv
head -n10
is to print only the 10 first line of the sort
output.
How to sort an array in Bash
You don't really need all that much code:
IFS=$'\n' sorted=($(sort <<<"${array[*]}"))
unset IFS
Supports whitespace in elements (as long as it's not a newline), and works in Bash 3.x.
e.g.:
$ array=("a c" b f "3 5")
$ IFS=$'\n' sorted=($(sort <<<"${array[*]}")); unset IFS
$ printf "[%s]\n" "${sorted[@]}"
[3 5]
[a c]
[b]
[f]
Note: @sorontar has pointed out that care is required if elements contain wildcards such as *
or ?
:
The sorted=($(...)) part is using the "split and glob" operator. You should turn glob off:
set -f
orset -o noglob
orshopt -op noglob
or an element of the array like*
will be expanded to a list of files.
What's happening:
The result is a culmination six things that happen in this order:
IFS=$'\n'
"${array[*]}"
<<<
sort
sorted=($(...))
unset IFS
First, the IFS=$'\n'
This is an important part of our operation that affects the outcome of 2 and 5 in the following way:
Given:
"${array[*]}"
expands to every element delimited by the first character ofIFS
sorted=()
creates elements by splitting on every character ofIFS
IFS=$'\n'
sets things up so that elements are expanded using a new line as the delimiter, and then later created in a way that each line becomes an element. (i.e. Splitting on a new line.)
Delimiting by a new line is important because that's how sort
operates (sorting per line). Splitting by only a new line is not-as-important, but is needed preserve elements that contain spaces or tabs.
The default value of IFS
is a space, a tab, followed by a new line, and would be unfit for our operation.
Next, the sort <<<"${array[*]}"
part
<<<
, called here strings, takes the expansion of "${array[*]}"
, as explained above, and feeds it into the standard input of sort
.
With our example, sort
is fed this following string:
a c
b
f
3 5
Since sort
sorts, it produces:
3 5
a c
b
f
Next, the sorted=($(...))
part
The $(...)
part, called command substitution, causes its content (sort <<<"${array[*]}
) to run as a normal command, while taking the resulting standard output as the literal that goes where ever $(...)
was.
In our example, this produces something similar to simply writing:
sorted=(3 5
a c
b
f
)
sorted
then becomes an array that's created by splitting this literal on every new line.
Finally, the unset IFS
This resets the value of IFS
to the default value, and is just good practice.
It's to ensure we don't cause trouble with anything that relies on IFS
later in our script. (Otherwise we'd need to remember that we've switched things around--something that might be impractical for complex scripts.)
How can I add a column of ascending numbers for each scaffold in my bed file
All right, I finished a bash script that will do exactly what you need. Go ahead and save the following as num_count.sh (or whatever you want as long as it's a shell script format) and it should do the trick for you:
#!/bin/bash
#Color declarations
RED='\033[0;31m'
GREEN='\033[0;32m'
LIGHTBLUE='\033[1;34m'
LIGHTGREEN='\033[1;32m'
NC='\033[0m' # No Color
#Ignore the weird spacing. I promise it looks good when it's echoed out to the screen.
echo -e ${LIGHTBLUE}"############################################################"
echo "# Running string counting script. #"
echo "# #"
echo -e "# ${LIGHTGREEN}Syntax: num_count.sh inputFile outputFile${LIGHTBLUE} #"
echo "# #"
echo "# The script will count the number of instances of #"
echo "# the first string and increment the number as it #"
echo "# finds a new one, appending it to the end of each line. #"
echo -e "############################################################"${NC}
numCount=0
oldStr=null
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Insufficient arguments. Please correct your parameters and run the script again."
exit
fi
> $2
while IFS= read -r line; do
firstStr=$(echo $line | awk '{print $1;}')
if [ $oldStr == $firstStr ] ; then
((numCount++))
echo -e "$line\t$numCount" >> $2
else
oldStr=$firstStr
numCount=0
echo -e "$line\t$numCount" >> $2
fi
done < $1
Essentially, you'll need to run the script with the first argument as the file that contains the lines you want counted, and the second argument as the output file. Be careful because the output file will be overwritten with the output data. I hope this helps!
Here's the before and after:
Before:
SCF_1 0 1
SCF_1 3 4
SCF_1 9 10
SCF_2 0 1
SCF_2 4 5
SCF_2 12 13
SCF_2 23 24
SCF_2 79 80
SCF_3 2 3
SCF_4 1 2
After:
SCF_1 0 1 0
SCF_1 3 4 1
SCF_1 9 10 2
SCF_2 0 1 0
SCF_2 4 5 1
SCF_2 12 13 2
SCF_2 23 24 3
SCF_2 79 80 4
SCF_3 2 3 0
SCF_4 1 2 0
Related Topics
Shell Script Continues to Run Even After Exit Command
How to Schedule a Cron for The First Thursday of Every Month
Postgres Copy Command, Binary File
Use "Git Revert" to Back-Out a Change Adding a Line
Accidentally Deleted Symlink Libc.So.6 in Centos 6.4. How to Get Sudo Privilege to Re-Create It
Linux Set End of File (Shrink, Truncate, Cut Out Some Data @ End)
Find Installation Path in Linux
Possible I/O Sync Issue with Ruby Script Under Nohup
Gfortran: Compiling 32-Bit Executable in 64-Bit System
How to Fix Urllib3 Runtimeerror: Requests Dependency 'Urllib3' Must Be Version >= 1.21.1, < 1.22
Numa-Aware Named Shared Memory for Linux
Npm Install -G Grunt-Cli Failed in Linux
Git - How to Remove Branch from Checkout Autocomplete
Dynamically Pick The User Gui and UId Who's Running Docker at The Host from Entrypoint
Installing PHPsh on Linux, Python Error
How to Detect Whether Tomcat and Ant Are Installed on Linux Machine
How to Modify The Linux Kernel to Change The Version String That Uname Returns