Print arguments using array elements not working?


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Print arguments using array elements not working?
# 15  
Old 05-06-2013
Like I said I'm new to this and I tried to explain it the best I could. I'll try to give the full run down. I have a 46 column data input file that looks like this:
Code:
3701 09 39 51.42 85 22 48.02  15.544   0.661  16.349  0.0368  16.193  0.0122  15.535  0.0117
3800 09 35 45.07 85 14 19.24  15.908   0.728  16.808  0.0320  16.615  0.0124  15.906  0.0117
3825 09 44 39.06 85 12 04.66  16.113   0.734  17.046  0.0319  16.823  0.0123  16.107  0.0117
3829 09 39 52.06 85 11 44.99  16.252   0.787  17.295  0.0334  17.015  0.0125  16.246  0.0117
3935 10 16 09.40 85 22 22.69  16.246   0.744  17.229  0.0314  16.968  0.0120  16.237  0.0117
3942 10 02 09.58 85 21 58.22  14.464   1.043  16.348  0.0306  15.484  0.0123  14.453  0.0116
3977 10 08 41.28 85 19 20.60  16.165   0.733  17.149  0.0358  16.874  0.0121  16.153  0.0117
3978 09 54 39.79 85 19 16.53  15.980   0.804  17.183  0.0307  16.754  0.0121  15.963  0.0117
3979 10 19 42.93 85 19 12.80  16.170   0.828  17.424  0.0360  16.977  0.0104  16.159  0.0113
4006 09 52 01.37 85 18 18.69  14.936   1.012  16.688  0.0335  15.919  0.0122  14.928  0.0117
4014 09 57 00.09 85 17 49.63  16.231   0.730  17.208  0.0361  16.932  0.0122  16.223  0.0117
4063 10 14 22.03 85 14 37.34  15.716   0.707  16.614  0.0263  16.400  0.0103  15.711  0.0112
4065 10 11 55.20 85 14 32.15  15.470   0.679  16.314  0.0262  16.127  0.0104  15.464  0.0113
4075 09 52 56.26 85 13 41.39  15.698   0.660  16.498  0.0256  16.339  0.0120  15.690  0.0115
4119 10 20 50.27 85 09 55.13  15.772   0.713  16.645  0.0285  16.463  0.0119  15.759  0.0117
4163 10 51 58.58 85 26 10.99  15.572   0.672  16.408  0.0262  16.228  0.0129  15.575  0.0125
4177 10 53 05.07 85 25 04.96  15.344   0.670  16.165  0.0253  16.009  0.0098  15.344  0.0096
4200 10 49 28.47 85 23 02.22  14.927   0.763  16.024  0.0102  15.651  0.0071  14.903  0.0084
4228 10 35 44.83 85 20 33.71  13.942   1.047  15.784  0.0217  14.963  0.0091  13.927  0.0110
4240 11 00 20.23 85 19 56.52  15.988   0.698  16.890  0.0299  16.659  0.0086  15.975  0.0092
4248 10 27 30.88 85 19 14.33  15.848   0.695  16.719  0.0287  16.518  0.0104  15.836  0.0113
4250 10 44 38.15 85 19 06.81  15.830   0.676  16.658  0.0276  16.472  0.0086  15.813  0.0092
4254 10 37 33.60 85 18 38.93  15.816   0.684  16.667  0.0275  16.480  0.0103  15.805  0.0113
4257 10 58 11.40 85 18 35.19  14.914   0.713  15.861  0.0159  15.599  0.0079  14.897  0.0089
4267 10 58 58.07 85 18 07.43  15.335   0.693  16.209  0.0242  15.999  0.0085  15.323  0.0090
4268 10 52 53.96 85 17 57.84  14.916   0.742  15.922  0.0215  15.621  0.0085  14.900  0.0090

Obviously I didn't include all 46 columns and 200-some rows but you get the idea. What I want to be able to do is write a script that asks for which columns to take from the input and write to the output. The problem is I could want 4 columns or I could want 10 columns to be written out. I have the code first prompt for the input file name so I don't need to hard-code that, and for the user to give whatever output file name you want.
Code:
# Get input file from user
echo "Provide name of master file for use"
read infile
sed '1,3d;$d' $infile > infilemod

# Get output file name from user
echo "Provide desired output file name"
read outfile

Notice that I remove the first 3 lines and the last line from the input file just because those are some header lines that I don't need. Next I have the code ask for how many columns to be copied to the output file, and I store that in the variable num:
Code:
# Get number of columns to be included
echo "Enter how many columns to be used"
read num

Now that the script knows how many columns I want to take from the input file, I use a for loop to ask which columns are to be copied:
Code:
echo "Provide the desired columns to be included Press [enter] after each"
for (( i = 0 ;  i < $num;  i++ ))
do
 read choices[i]
done

No matter which columns I choose I always want to print the first column of the input file to the first column of the output file so I use this:
Code:
awk ' { print $1, " " } ' infilemod >temp1

So at this point I have a file called temp1 that has just the first column printed with a space after. Now I use another loop to try to loop over the choices of columbs to be printed:
Code:
for (( i = 0 ;  i < $num;  i++ ))
do
 awk -v f2=temp1 -v c=${choices[$i]} ' { getline < f2; print $0, c, " "; } ' infilemod >temp2
 mv temp2 temp1
done

The way I've written it is just so that awk adds columns to the file temp1 rather than writing over top of them. You can think of it as put in first column of the input file, then put in each column from the input file that you specified. This is where the problem comes in though. It does not print the column c as I have it written. I just get the blank spaces. Very frustrating!

Finally I have the code put in a header line to the output file that I have stored in another file called header.txt and remove the temp files that I used.
Code:
# Add header
cat header.txt temp1 > tmp; mv tmp $outfile

# Remove extra files
rm infilemod
rm temp1
exit 0

Hopefully this is clearer now. Sorry about all the confusion. I really appreciate the help!
# 16  
Old 05-07-2013
Hi shaner,
You still have not provided any sample output, but I think the following bash/awk script will do what you want. Note that this shell script gets its parameters from the command line instead of carrying on an interactive dialog with the user. This script does a lot more user input validation than the snippets of your code did.

I normally use ksh rather than bash, but there is a bug in the way ksh version sh (AT&T Research) 1993-12-28 s+ handles ${var#*[!0-9]} if the expansion of $var contains an exclamation point character (!) at least on OS X. If your users will never type in an exclamation point when entering a field number to be copied from the input file to the output file, both a current bash and a ksh93 or later version of the Korn shell will produce the same results with this script. (As always, if you want to run this on a Solaris/SunOS system, use /usr/xpg4/bin/awk, /usr/xpg6/bin/awk, or nawk rather than awk.)

This is a big script for this forum, but the vast majority of the code is comments. The comments explain the assumptions I made (many of which were not mentioned in your requirements).

Code:
#!/bin/bash
# USAGE:
#       maybe input_file output_file new_headers_file field_number...
#
# DESCRIPTON:
#       The maybe utility copies fields specified by the "field_number"
#       operands from the input file specified by the "input_file" operand to
#       the ouput file named by the "output_file" operand.  The first three
#       lines and the last line of the input file shall be skipped.  The
#       contents of the file named by the "new_headers_file" operand shall be
#       copied to the output file before any other data is copied from the
#       input file to the output file.  Fields in the input file are assumed to
#       be separated by one or more spaces and tabs.  Leading and trailing
#       spaces and tabs in the input file shall be ignored.  Fields written to
#       the output file shall be separated by a single tab character.  The
#       output fields shall be written to the output file in the order
#       specified by the "field_number" operands in order from beginning to end.
#
#       The results are unspecified if the input file is not a text file.
#
#       If a "field_number" operand specifies a field that does not exist in
#       the input file, an empty field will be written to the output file in
#       the corresponding output field.  Input fields are numbered starting
#       with 1.  If a "field_number" operand is 0, the entire input line will
#       be inserted at that point in the output.
#
# RATIONALE:
#       The name of this utility is chosen because this script may be doing
#       what the original poster in this thread wants.  The description of what
#       is supposed to happen has only been described by brief text and samples
#       fo code that doesn't work.  No sample output has been provided.  No
#       input with headers has been provided.

# Initialize global variables:
IAm=${0##*/}    # Final component of pathname used to invoke this script.
Usage="Usage: %s input_file output_file new_headers_file field_number..."

# Process command line arguments:
if [ $# -lt 4 ]
then    printf "%s: Not enough operands.\n$Usage\n" "$IAm" "$IAm" >&2
        exit 1
fi
if [ ! -r $1 ] || [ ! -r $3 ]
then    printf "%s: input_file or new_headers_file not readable.\n" "$IAm" >&2
        printf "$Usage\n" "$IAm" >&2
        exit 2
fi
inf="$1"
outf="$2"
nhf="$3"
shift 3

# Capture the remaining operands as an array of field_numbers
fn=( "$@" )

# Verify that each field number is non-null and only contain digits.
i=0
while [ $i -lt ${#fn[@]} ]
do      if [ ${#fn[$i]} -lt 1 ] || [[ "${fn[$i]}" != "${fn[$i]#*[!0-9]}" ]]
        then    printf "%s: field_number is not numeric.\n$Usage\n" "$IAm" \
                        "$IAm" >&2
                exit 3
        else    i=$((i + 1))
        fi
done

# Copy desired headers to output file.
if ! cat "$nhf" > "$outf"
then    printf "$Usage\n" "$IAm" "$IAm" >&2
        exit 4
fi

# Invoke awk to gather and print the requested fields after throwing away the
# 1st three header lines and the last trailer line.
printf "%d\n" ${fn[@]} | awk '
FNR == NR {
        # Read list of fields to be printed from standard input...
        fn[++nf] = $1
        next
}
FNR <= 3 {
        # Skip 3 header lines from 2nd input file.
        next
}
out != "" {
        # Print the results from the previous input line.  (Note that we also
        # have to skip the last line read for some unspecified reason.  The
        # delayed print allows us to do that since we do not print the last
        # line when we hit EOF.)
        print out
}
{       # Save requested fields (to be printed when we read the next line).
        for(i = 1; i <= nf; i++)
                i == 1 ? out = $fn[1] : out = out "\t" $fn[i]
}' - "$inf" >> "$outf"

This User Gave Thanks to Don Cragun For This Post:
# 17  
Old 05-07-2013
Dear Don Cragun,

Thanks so much! This works great and is exactly what I was trying to do. Sorry again for all the miscommunication on my part, I really appreciate the help!
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Select / Print odd-even elements of an array

Hello experts, I wish to print the contents of odd-even numbered indices of an array. The problem statement is as follows : 1. The first line contains an integer, (the number of test cases). 2. Each line of the subsequent lines containing a string. Example: 2 Haider Bash ... (4 Replies)
Discussion started by: H squared
4 Replies

2. Shell Programming and Scripting

Help reading the array and sum of the array elements

Hi All, need help with reading the array and sum of the array elements. given an array of integers of size N . You need to print the sum of the elements in the array, keeping in mind that some of those integers may be quite large. Input Format The first line of the input consists of an... (1 Reply)
Discussion started by: nishantrefound
1 Replies

3. UNIX for Dummies Questions & Answers

How to declare an array in UNIX and print the elements with tab delimits?

Hello, In a shell script, I want to declare an array and subsequently print the elements with tab delimits. My array has the following structure and arbitrary elements: myArray=('fgh' 'ijk' 'xyz' 'abc'); Next, I would like to print it with a '\n' at the end. Thanks for your input! ... (2 Replies)
Discussion started by: Gussifinknottle
2 Replies

4. Shell Programming and Scripting

Removing elements from an array

Hi I have two arrays : @arcb= (450,625,720,645); @arca=(625,645); I need to remove the elements of @arca from elements of @arcb so that the content of @arcb will be (450,720). Can anyone sugget me how to perform this operation? The code I have used is this : my @arcb=... (3 Replies)
Discussion started by: rkrish
3 Replies

5. Shell Programming and Scripting

working with null elements in an array

i have an array (with each element length "n") which is dynamic and has alphanumeric characters. i want to check if any of the elements of the array are null and replace it with a string of "n" zeros for that element. can you suggest me a code for the same. (1 Reply)
Discussion started by: mumbaiguy07
1 Replies

6. UNIX for Dummies Questions & Answers

printing array elements

Is there a way to print multiple array elements without iterating through the array using bash? Can you do something like... echo ${array}and get all those separate elements from the array? (2 Replies)
Discussion started by: jrymer
2 Replies

7. Shell Programming and Scripting

Store all the passed arguments in an array and display the array

Hi I want to write a script which store all the parameters passed to the script into an array. Once it is stored I want scan through the array and and delete those files for last month present inside the directory. The files in directory is appneded with YYYY_MM_DD. I want to know how can I... (3 Replies)
Discussion started by: dgmm
3 Replies

8. Shell Programming and Scripting

How can I print array elements as different columns in bash?

Hi Guys, I have an array which has numbers including blanks as follows: 1 26 66 4.77 -0.58 88 99 11 12 333 I want to print a group of three elements as a different column in a file as follows:(including blanks where there is missing elements) for.e.g. array element #7... (4 Replies)
Discussion started by: npatwardhan
4 Replies

9. UNIX for Dummies Questions & Answers

Deleting Array Elements

Hi, I am writing a BASH shell script. I have an array that will contain IN ANY ORDER the following elements: DAY 8D MO NS. I would like to erase the element DAY, but since the order of the elements in the array are random, I will not know which element # DAY is (ie it's not as simple as... (3 Replies)
Discussion started by: msb65
3 Replies

10. Shell Programming and Scripting

To return the elements of array

Hi, Please can someone help to return the array elements from a function. Currently the problem I face is that tempValue stores the value in myValue as a string while I need an array of values to be returned instead of string. Many Thanks, Sudhakar the function called is: ... (5 Replies)
Discussion started by: Sudhakar333
5 Replies
Login or Register to Ask a Question