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 Commented Nov 3, 2015 at 8:04
  • The actual csv file does not have any spaces 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? 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 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.