LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Need help create a bash script to edit CSV File (https://www.linuxquestions.org/questions/programming-9/need-help-create-a-bash-script-to-edit-csv-file-663835/)

imkornhulio 08-19-2008 09:47 AM

Need help create a bash script to edit CSV File
 
i need to edit 4th field in the CSV file (i need to subtract 5 from whatever number is their in the fourth field, if the number is negative then replace it with 0)
The separator is ,

Please help

colucix 08-19-2008 09:52 AM

Can you post some lines of the CSV file as example? What have you tried until now?

imkornhulio 08-19-2008 09:52 AM

Online,World,20080819,0,1200M05,045468004016,N,,42,94,,,,,,N
Online,World,20080819,13,1200M055,045468004023,N,,42,94,,,,,,N
Online,World,20080819,0,1200M06,045468004030,N,,42,94,,,,,,N
Online,World,20080819,67,1200M065,045468004047,N,,42,94,,,,,,N

i tried to use awk but i am not that familiar with it

colucix 08-19-2008 10:24 AM

Using awk you can do something like this:
Code:

awk -F, '                                                             
BEGIN{OFS=","}
{if ($4 < 5)
    $4 = 0;
else
    $4 = $4 - 5
print}' file

I think the code is self-explaining. I put it on multiple lines to make it more clear. If you're looking for a solution in pure bash, well... it is a bit more complicated.

imkornhulio 08-19-2008 10:36 AM

is it possible to do it in Bash. i am not familiar on how to use awk.
Can i use awk in bash as a command and create a script?

colucix 08-19-2008 11:11 AM

Quote:

Originally Posted by imkornhulio (Post 3252694)
Can i use awk in bash as a command and create a script?

Of course. You can use awk in a shell script as any other external command (I use the term external commands here to distinguish between them and the shell built-ins). Depending on what you're trying to do, you may need something like this:
Code:

#/bin/bash
awk -F, 'BEGIN{OFS=","}{if ($4 < 5) $4 = 0; else $4 = $4 - 5; print}' /path/to/input/file > /path/to/output/file


imkornhulio 08-19-2008 11:35 AM

works like a charm

Thanks a lot

colucix 08-19-2008 11:53 AM

You're welcome! :)

Here is a bash solution, too
Code:

#!/bin/bash
declare -a array

# Store the original input field separator
OLD_IFS=$IFS

while read line
do
  # Load the comma separated fields into array
  IFS=','
  array=(`echo "$line"`)
 
  # Do arithmetics on 4th element
  if [ ${array[3]} -lt 5 ] ; then
    array[3]=0
  else
    array[3]=$((${array[3]} - 5))
  fi

  # Print a "comma separated" array
  printf "%s," ${array[@]} | sed 's/,$//'
  echo
done < testfile

# Restore the original input field separator
IFS=$OLD_IFS

this does not use awk, but uses sed as external command to strip out the trailing comma when printing the content of the array. Maybe there is a better way to do.

imkornhulio 08-26-2008 07:40 AM

I used the awk script and ran it in the cron job. but when i run the cron job the output file shows 0bytes. When i run it manually it runs fine. Can someone help me resolve this problem. I changed the file rights and the directory rights and gave them both 777 permission. NEED HELP!!!

Thanks

colucix 08-27-2008 05:04 AM

The crontab has a very limited environment, different from what you get upon login. The PATH is usually limited to /bin:/usr/bin, so that a good rule is to specify the absolute path of all the commands in the script. You can also look at the mail of the user owning the crontab to see if there is any error message. On most systems the cron daemon sends the standard output and the standard error to the user's mail, unless they are redirected to a file. Feel free to post the whole script and the crontab entry to let us take a look at what the problem is.

imkornhulio 08-29-2008 09:51 AM

It worked out great. I put in full path in the script and worked like a charm.

Thanks a lot

imkornhulio 02-04-2009 02:04 PM

help
 
Quote:

Originally Posted by colucix (Post 3252723)
Of course. You can use awk in a shell script as any other external command (I use the term external commands here to distinguish between them and the shell built-ins). Depending on what you're trying to do, you may need something like this:
Code:

#/bin/bash
awk -F, 'BEGIN{OFS=","}{if ($4 < 5) $4 = 0; else $4 = $4 - 5; print}' /path/to/input/file > /path/to/output/file


the script doesn't work if the separator is "|"

awk -F, 'BEGIN{OFS="|"}{if ($4 < 5) $4 = 0; else $4 = $4 - 5; print}' /path/to/input/file > /path/to/output/file

Please help

colucix 02-04-2009 11:37 PM

Quote:

Originally Posted by imkornhulio (Post 3432248)
awk -F, 'BEGIN{OFS="|"}{if ($4 < 5) $4 = 0; else $4 = $4 - 5; print}' /path/to/input/file > /path/to/output/file

This code works for me in respect of your modification. You have changed the Output Field Separator but maybe you meant the Input Field Separator, didn't you?! If this is the case, just restore the OFS variable and modify the value of the option -F
Code:

awk -F"|" 'BEGIN{OFS=","}{if ($4 < 5) $4 = 0; else $4 = $4 - 5; print}' /path/to/input/file > /path/to/output/file
In an awk program the input field separator is simply FS. The -F option is just a quick shortcut for the assignment of FS. If you want to explicitly assign it within the awk code, just add it to the BEGIN section:
Code:

awk 'BEGIN{FS="|"; OFS=","}{if ($4 < 5) $4 = 0; else $4 = $4 - 5; print}' /path/to/input/file > /path/to/output/file

imkornhulio 02-05-2009 10:23 AM

Thanks


All times are GMT -5. The time now is 10:33 AM.