1

I'm working on a csv file that manage the students groups. I made a script that gets three arguments: student ID, type of group and group ID. There are two type of groups, problem or practice.

The thing is that I want the script to modify the csv file , specifically the group.

So my input will look like

./script.sh niubXXXXXX problems A00

This input will change the student with the ID "niubXXXXXX" to problem grups A00. So the thing is I created a script that actually manages to work properly(it does that I want to do) but can't overwrite the csv file in order to change it.

#!/bin/bash

if [ ! $# -eq 3 ]
then
    echo "Falta argument. Usage: ./script5.sh directori "
    exit 1
fi
alumne=$1
columna=$2
grupCanvi=$3

if [ "$columna" = "problemes" ]
then
    awk -F';' -v OFS=';' -v id=$alumne -v new_group=$grupCanvi 
'{if($1==id)$3=new_group}1' ./alumnes.csv > ./alumnes.csv

    echo "Grup de problemes modificat"
fi

if [ "$columna" = "practiques" ]
then
    awk -F';' -v OFS=';' -v id=$alumne -v new_group=$grupCanvi 
'{if($1==id)$2=new_group}1' ./alumnes.csv > ./alumnes.csv

    echo "Grup de pràctiques modificat"
fi

So the thing is when I put the code like this:

awk -F';' -v OFS=';' -v id=$alumne -v new_group=$grupCanvi 
'{if($1==id)$2=new_group}1' ./alumnes.csv >> ./alumnes.csv

(to append, not to overwrite)

It works properly, append it just below my last list just like I wanted but, when I try to overwrite it, the csv file just goes empty.

The csv file structure look like this:

IUB;Grup Pràctiques;Grup Problemes
niubXXXXXXXX;B00;CF0
niubXXXXXXXX;A00;CF0
niubXXXXXXXX;C00;CF0
niubXXXXXXXX;F00;AB0

Any idea of what happens when I try to overwrite the csv file?

Yeste
  • 135
  • 10

1 Answers1

2

Trying to modify the same data structure you are reading is never a good idea. If you traverse a list and you are reading element n and you decide you want to remove it, which element should be the next to read? n or n+1?

A similar thing happens here. As soon as bash processes your command, it sees that there is an output redirection, so it opens and truncates the file for writing, once the redirections are prepared, it starts your script, whose input is the now empty file, so nothing else is written there.

In short: don't write to the same file you are reading. Usual tecnique is to write to a temporary file and, when finished, substitute the original file (command input>temp; rm input; mv temp input). Other tricks include the use of some software that explicitly allows for inline modifications (like sed -i) or utilities like sponge, from moreutils.

Your code could be:

awk -F';' -v OFS=';' -v id=$alumne -v new_group=$grupCanvi '{if($1==id)$2=new_group}1' ./alumnes.csv > ./alumnes.csv.tmp
rm ./alumnes.csv
mv ./alumnes.csv.tmp 
Poshi
  • 5,332
  • 3
  • 15
  • 32