1

There is a acc.csv file, that contains name and surname in 3rd column (ex: john smith). I try capitalize firt letters (John Smith) and create a new file acc_new.csv with this:

#!/bin/bash

while IFS=, read -r col1 col2 col3 

do
    for n in $col3; do
        n=${n^}
    done  

done < acc.csv > acc_new.csv

But acc_new.csv is empty. What is wrong with code?

acc.csv:

id,location,name
1,1,john smith
2,2,paul Robinson
3,3,Fidel guererro
...

expected output:

id,location,name
1,1,John Smith
2,2,Paul Robinson
3,3,Fidel Guererro
...
diz
  • 13
  • 3

4 Answers4

2

The original bash code read in and modified the contents of acc.csv, but did not organize or export the modified contents.

The modified code may help:

#!/bin/bash

while IFS=, read -r col1 col2 col3 

do
    unset col3_new

    if [ "$col1" == id ]; then
        echo "${col1},${col2},${col3}"
        continue
    fi

    for n in $col3; do
        if [ -z "$col3_new" ]
        then
            col3_new=${n^}
        else
            col3_new+=" ${n^}"
        fi
    done  
    echo "${col1},${col2},${col3_new}"

done < acc.csv > acc_new.csv
wiliam
  • 51
  • 3
1

You could do this in pure bash as you're attempting, but it's likely more efficient in another language.

Perl example:

$ perl -F, -lane '$F[2] =~ s/\b([[:alpha:]])/\u$1/g if $. > 1;
                  print join(",", @F)' acc.csv > acc_new.csv
$ cat acc_new.csv
id,location,name
1,1,John Smith
2,2,Paul Robinson
3,3,Fidel Guererro

This titlecases every letter in the third column (Skipping the first header line) at a word break - like the start of the field or after a space.

Shawn
  • 47,241
  • 3
  • 26
  • 60
0

If you do not mind using a line of perl ...

sample :

name,job,fee
aaaa,bbb,ccc

code

perl -lne 's/^./uc($&)/e  && print' < my.csv

or

perl -lne 's/^./\u$&/g  && print' < my.csv

output:

Name,job,fee
Aaaa,bbb,ccc

For your case that starts with numbers try this

perl -lpe 's/(?<=,)[a-z]/\u$&/ ' < smple.csv

output

id,Location,name
1,1,John smith
2,2,Paul Robinson
3,3,Fidel guererro

and if you want that only lines started with numbers be affected , first match numbers

perl -lpe '/^\d/ && s/(?<=,)[a-z]/\u$&/ ' < smple.csv

ref

oguz ismail
  • 1
  • 16
  • 47
  • 69
Shakiba Moshiri
  • 21,040
  • 2
  • 34
  • 44
  • @oguz-ismail I linked that lines be in orange color, the same theme as stack-over-flow has ... – Shakiba Moshiri May 27 '20 at 09:41
  • I got it, let's focus on the quality of the content rather than the aesthetic value – oguz ismail May 27 '20 at 09:43
  • @oguzismail it is your opinion and not mine. Quality of an answer is scored by Up-vote / Down-vote not what I, you/, others think it is. Here is another answer of mine please read the first comments by **KamilCuk** [Bash - Clearing the last output correctly](https://stackoverflow.com/questions/62038398/bash-clearing-the-last-output-correctly) – Shakiba Moshiri May 27 '20 at 09:59
  • I didn't say your question is of low quality. What I meant was there is no point in decorating your post with colorful images, etc. since it doesn't add any extra value. – oguz ismail May 27 '20 at 10:28
0

Here's a solution using bash and awk

#!/bin/bash

cat acc.csv | awk '
    BEGIN {OFS=FS=","};
    NR>1{
        $3 = tolower($3);
        split($3, arr, " ");
        for(i in arr)
            sub(arr[i], toupper(substr(arr[i], 1, 1))substr(arr[i], 2), $3)
    }1' > acc_new.csv