Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have not tried the script yet ... but i have the same working in Excel that i have been using from 2 years. But i had few problems like macros getting corrupted or the excel itself gets corrupted. So i wanted to have something in script form.
Now I'm confused. Excel scripts are not, usually, written in bash. I believe that Excel expects the script to be in Visual Basic, a Microsoft propitiatory language.
If you are moving from Excel to Open Office Calc, there is a scripting language you can use, but it's notbash.
The data input to the excel comes manually from a sequence of commands. And i use excel to process the data how i want using macros, formulas etc and use the output from excel to run bunch of other commands inputting excel processed data. So i want to remove the excel from the picture and automate everything using the script. Does it makes sense ?
Here's a bash script that will do it for your example data:
Code:
#/bin/bash
###########################################################
# Storage array:
# size[] - Different size values
declare -a size
# Associative arrays
# id[] - List of ids for each specific size
# count[] - Number of times each size value occurs
declare -A id count
############################################################
#
# Function to read the input data file and set up the arrays
#
# Argument: $1 - Path of the input data file
#
read_data()
{
local i j n
local ID SIZE
declare -a line
local failed
failed=""
# Read the input file into the "line" array, skipping the first line
mapfile -s 1 -t line < "${1}"
# Parse each line of input (two values: ID and Size)
for ((i=0;i<${#line[*]};++i))
do
j=0
for n in ${line[${i}]}
do
j=$((++j))
if [ ${j} -eq 1 ]
then ID=${n}
fi
if [ ${j} -eq 2 ]
then SIZE=${n}
fi
done
# Did this row contain exactly two values?
if [ ${j} -ne 2 ]
then
echo "Line " i " (${line[${i}]}) in the file \"" ${1} "\" contains " ${j} " symbols." > /dev/stderr
failed="failed"
else
# Initialize this size[] entry if this is a new SIZE
if [ -z "${size[${SIZE}]}" ]
then
size[${SIZE}]=${SIZE}
count[${SIZE}]=1
id[${SIZE}]=${ID}
else
# Otherwise, just update the id[] list and the count[] entry
id[${SIZE}]="${id[${SIZE}]}:${ID}"
count[${SIZE}]=$((++count[${SIZE}]))
fi
fi
done
# Set the function succeed/fail code and return
[ -z "${failed}" ] && return 0
return 1
}
##############################################################
#
# Function to find the first "Count" values of size "Size"
#
# Arguments: $1 Size; $2 Count
#
get_first_n_values()
{
# Initialization
local Size Count i n ret ifs
Size=${1}
Count=${2}
ret=""
n=1
ifs="$IFS"
IFS=":"
for i in ${id[${Size}]}
do
ret="${ret}${i} "
[ ${n} -eq ${Count} ] && break
n=$((1+${n}))
done
# Restore the field separator
IFS="$ifs"
# Did we find "Count" values?
if [ ${n} -ne ${Count} ]
then
ret=""
fi
# O.K., pass the list back (null on error}
echo "$ret"
[ -z "$ret" ] && return 1
return 0
}
##############################################################
#
# Function to find the first sequence "Count" values of size "Size"
#
# Arguments: $1 Size; $2 Count
#
get_first_n_sequential_values()
{
local Size Count i n ret ifs
local -a seq
# Initialization
Size=${1}
Count=${2}
# Basic sanity check
[ -z $count[$Size] ] && echo "There are no entries for size $Size." && echo "" && return 1
# Secondary initialization
ifs="${IFS}"
IFS=":"
ret=""
n=0
# Loop through the list of values of the specified size
#
# Note that the values are ASSUMED to be in hexadecimal
# so the are prefixed by the 0x "hexadecimal" before use.
#
for i in ${id[${Size}]}
do
# If we've started a sequential list, check for this value being the
# "next" one. If not, set the count back to zero
[ ${n} -gt 0 ] && [ $((0x${seq[$((${n}-1))]})) -ne $((0x${i} - 1)) ] && n=0
# Add the current value to the list and increment the list length count
seq[${n}]=${i}
n=$((++n))
# Do we have the specified number of values?
if [ ${n} -eq $((${Count})) ]
then
# OK, build the return string (which was empty 'till now)
for ((j=0;j<${Count};++j))
do
ret="${ret}${seq[${j}]} "
done
break
fi
done
# Clean up
IFS="$ifs"
# All done. Return the string, empty on error
echo "$ret"
[ -z "$ret" ] && return 0
return 1
}
#########################################################################
#
# Main program
#
# Arguments:
#
# $1 - Input data file (Pairs of "Size Value" entries
# $2 - Size to extract
# $3 - Number of values to list
# $4 - Flag. "y" for a sequential list, "n" for a simple list
#
# The extraction triple ($[2 3 4]) may be repeated as many times as needed
#############################################################################
#
# First, verify that the specified input file exists and is readable
if ! [ -r "${1}" ]
then
echo "The file \"${1}\" is not readable."
exit
fi
# Read the data file (The file name is quoted because it might contain special characters)
read_data "${1}"
shift
# Process each triple in order
while [ $# -gt 2 ]
do
# Initialization
found=""
Size=$1
shift
Count=$1
shift
Sequential=$1
shift
# Sanity checks
[ -z ${size[$Size]} ] && echo "There are no entries of size $Size." && continue
[ ${Count} -le 0 ] && echo "Count must be greater than zero." && continue
[ ${Count} -gt ${count[${Size}]} ] && echo "There are only ${count[${Size}]} ${Size} values in the \"${1}\" file." && continue
# The :0:1 selects the first character in the "Sequential" string
ch=${Sequential:0:1}
# And the ^* converts it to upper case
ch=${ch^*}
if [ ${ch} == "N" ]
then
echo -n "List of the first ${Count} values of size ${Size}: "
else
echo -n "List of the first ${Count} consecutive values of size ${Size}: "
fi
# Process this argument triple
if [ ${ch} == "N" ]
then
ret=$(get_first_n_values ${Size} ${Count})
[ $? -ne 0 ] && continue
echo "$ret"
else
ret=$(get_first_n_sequential_values ${Size} ${Count})
if [ "${ret}" == "" ]
then
echo "None found."
else
echo "$ret"
fi
fi
done
And here's the test data I used and some output:
Code:
$ cat test_data
ID Size
1 8
2 8
3 16
5 16
7 8
8 8
9 8
a 16
c 16
e 8
f 8
$ ./parse_data test_data 8 3 n 8 3 y 8 4 n 8 4 y
List of the first 3 values of size 8: 1 2 7
List of the first 3 consecutive values of size 8: 7 8 9
List of the first 4 values of size 8: 1 2 7 8
List of the first 4 consecutive values of size 8: No sequence of 4 consecutive values of size 8 was found.
Last edited by PTrenholme; 12-06-2010 at 02:05 PM.
Reason: Added comments, fixed bug
PTrenholme .. Thank you looks to me you got what i need. I appreciate your time and effort. I am closing this thread as solved. I am going to take your script and start my first step to my goal to completion. :-)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.