1

How do I write a bash script that makes lists by by selecting a column of a spreadsheet which is in csv format?

If I have csv files that have these contents:

        [user]$ cat list1.csv
        Last, First, user
        lname1, fname1, user1
        lname2, fname2, user2

        [user]$ cat list2.csv
        Last, First, user
        lname3, fname3, user3
        lname4, fname4, user4

And I want the script to be invoked as CreateList <column> <file1> <file2> ...

For Example :

        [user]$ CreateList 2 list2.csv list1.csv
        list2: fname3, fname4
        list1: fname1, fname2
4
  • Ok, but what have you already tried? Commented Nov 3, 2015 at 8:03
  • your input is not a valid csv, unless the spaces are intentionally part of the strings
    – Dani_l
    Commented Nov 3, 2015 at 8:04
  • The actual csv file does not have any spaces
    – bbycakes3
    Commented Nov 3, 2015 at 8:07
  • Do you want your script to drop the first record (Last,First,user) and only print from 2nd record?
    – Dani_l
    Commented Nov 3, 2015 at 8:13

4 Answers 4

0

This is sh not bash, but bash can run it.

$ cat CreateList 
#!/bin/sh

col="$1"; shift

for file
do
        echo -n "$file:"
        cut -d, -f"$col" "$file" | sed 1d | tr '\n' ','| sed '$ s/,$//'
        echo
done

$ 
$ head -9 list*.csv
==> list1.csv <==
Last,First,user
lname1,fname1,user1
lname2,fname2,user2

==> list2.csv <==
Last,First,user
lname3,fname3,user3
lname4,fname4,user4
$ 

$ sh CreateList 2 list2.csv list1.csv
list2.csv:fname3,fname4
list1.csv:fname1,fname2
$ 
0

Simply invoke awk appropriately

# print first column:
cat list1.csv | awk '{ORS="\t"} {print $1}'

Or as complete script:

#!/bin/bash
column=$1
shift;
for item in "$@" ; do
  #process item
  echo "Processing $item:"
  cat $item | awk '{ORS="\t"} {print "'"$column"'"}'
done

Helpful:

https://stackoverflow.com/questions/2021982/awk-without-printing-newline https://stackoverflow.com/questions/19075671/how-to-use-shell-variables-in-awk-script

0

Perhaps not the most elegant solution, but this will provide the exact output you specified, including spaces:

#!/bin/bash

function CreateList()
{
  col="$1"
  shift
  cut -d ',' -f $col $@ | sed -r '1d ; s/^[ ]+|[ ]$// ; y/\n/ /; s/[ ]+$/\n/' | xargs echo | sed 's/ /, /'
}

for f in list2.csv list1.csv
do
  echo -n "${f//.csv}: "
  CreateList 2 "$f"
done

Output:

list2: fname3, fname4
list1: fname1, fname2
1
  • the cut line in the function could be simplified to: cut -d ',' -f1 list1.csv | sed -r '1d ; s/^[ ]+|[ ]$// ; y/\n/ /; s/[ ]+$/\n/' | xargs echo | sed 's/ /,/' - only runs sed twice rather than 4 times plus one tr
    – cas
    Commented Nov 3, 2015 at 8:49
0

Simple bash:

#!/bin/bash
clm=$(($1 - 1))
shift
for file
do
    printf "%s: " "$file" 
    unset res 
    {
        read
        while IFS=,\  read -a line
        do
            res=(${res[*]} ${line[$clm]}) 
        done
    } <"$file"
    printf "%b, " "${res[@]}"\\n\\c
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .