Search code examples
linuxbashawkshgawk

Replace certain field from file with user input for each row and save in same file


Im typing to write a script which can read file_name, delimiter and field_number. After that for each row take an input, replace the field (specified by field_number) and output to same file.

For example if the input is as follows:

Ritesh;M;1992
Shakya;F;1993

For the command

bash_script.sh test.csv ";" 3

Iterating through each row if I input 1994 for first and 1995 for second. I want the output to be the as follows caved in the same file.

Ritesh;M;1994
Shakya;F;1995

So far i managed to get upto this point:

#!/usr/bin/env bash
echo "Following is the input needed:";
echo "\$1: FILE_NAME";
echo "\$2: DELIMITER";
echo "\$3: FIELD IN NUMERIC VALUE";

gawk -i inplace -F "$2" '{...}' $1;

Also my version of gawk doesn't support -i. Thanks in advance.


Solution

  • Answer to first question

    If you only need to replace 1992 with 1994 and 1993 with 1995, you don't need a script, you can do it easily using sed:

    sed "s/;1992/;1994/g" test.csv | sed "s/;1993/;1995/g" 
    

    Output:

    [shell] ➤ sed "s/;1992/;1994/g" test.csv | sed "s/;1993/;1995/g"
    Ritesh;M;1994
    Shakya;F;1995
    

    If you also need to save the output you can add

    sed "s/;1992/;1994/g" test.csv | sed "s/;1993/;1995/g" > temp; mv temp test.scv 
    

    But if you want to use a script:

    #!/bin/bash
    
    if [ -z "${1}" ];then
            echo "Usage: $0 <filename>"
    else
            FILENAME=$1
            sed "s/;1992/;1994/g" $FILENAME| sed "s/;1993/;1995/g"
    fi
    

    Output:

    [shell] ➤ ./test3.sh
    Usage: ./test3.sh <filename>
    
    [shell] ➤ ./test3.sh test.csv
    Ritesh;M;1994
    Shakya;F;1995
    

    Script updated after last comment

    #!/bin/bash
    if [ -z "${3}" ];then
            echo "Usage: <filename> <delimiter> <field_no>"
    else
            FILENAME=$(readlink -f $1)
            DELIMITER=$2
            FIELD_NO=$3
            TEMP_FILE=/tmp/tempFile
            if [ -f $TEMP_FILE ]; then
                rm $TEMP_FILE
            fi
            for line in $(cat $FILENAME)
            do
                    oldValue=`echo $line|cut -d$DELIMITER -f$FIELD_NO`
                    echo "Enter the value to replace [$oldValue]"
                    read newValue
                    echo $line | sed "s/${oldValue}/${newValue}/g" >> $TEMP_FILE
            done
    fi
    mv $TEMP_FILE $FILENAME    
    

    I've commented the command #mv tempFile $FILENAME because it's your choice to rename the file or keep the new one.