Reputation: 19
Problem Description: I am trying to read the file test.csv, and add a variable $lastid (let's say 35 for the example) at the end of each line. But this variable needs to be incremented every two lines.
Expectations: I am expecting to get: for line 1 and 2 ",36" at the end of the line. for line 3-4 ",37" at the end of the line. for line 5-6 ",38" at the end of the line. and so on...
Script Code:
set -x ##debug mode on
lines=$( wc -l < test.csv ) ## you count the total of lines
lines=$((lines+1)) ## you increment it
g=$lastid ## this is the variable of my lastid_game from my database (let's say 35 for the example)
i=1
j=1
while [ $j -le $lines ] ## while my lines number is lower or equal than the total of lines
do
if [ $(( $j%2 )) -eq 0 ] ## if my line number is even
then
echo "number "$j" is even" ## I display it
j=$(( $j+1 )) ## I increment my lines
sed -e "s/$/,$g/" test.csv > test1.csv
else
echo "number "$j" is odd" ## I display my line is odd
g=$(( $g+1 )) ## I increment my id_game
j=$(( $j+1 )) ## I increment my lines
sed -e "s/$/,$g/" test.csv > test1.csv
fi
done
set +x ##debug mode off
Content of test.csv:
a,b,c,d,e,f
a,b,c,d,e,f
a,b,c,d,e,f
a,b,c,d,e,f
a,b,c,d,e,f
a,b,c,d,e,f
a,b,c,d,e,f
a,b,c,d,e,f
Current Output: ( which I believe is doing good)
++ wc -l
+ lines=46
+ lines=47
+ g=35
+ i=1
+ j=1
+ '[' 1 -le 47 ']'
+ '[' 1 -eq 0 ']'
+ echo 'number 1 is odd'
number 1 is odd
+ g=36
+ j=2
+ sed -e 's/$/,36/' test.csv
+ '[' 2 -le 47 ']'
+ '[' 0 -eq 0 ']'
+ echo 'number 2 is even'
number 2 is even
+ j=3
+ sed -e 's/$/,36/' test.csv
+ '[' 3 -le 47 ']'
+ '[' 1 -eq 0 ']'
+ echo 'number 3 is odd'
number 3 is odd
+ g=37
+ j=4
+ sed -e 's/$/,37/' test.csv
+ '[' 4 -le 47 ']'
+ '[' 0 -eq 0 ']'
+ echo 'number 4 is even'
number 4 is even
+ j=5
+ sed -e 's/$/,37/' test.csv
+ '[' 5 -le 47 ']'
+ '[' 1 -eq 0 ']'
+ echo 'number 5 is odd'
number 5 is odd
+ g=38
+ j=6
+ sed -e 's/$/,38/' test.csv
+ '[' 6 -le 47 ']'
+ '[' 0 -eq 0 ']'
+ echo 'number 6 is even'
number 6 is even
+ j=7
+ sed -e 's/$/,38/' test.csv
+ '[' 7 -le 47 ']'
+ '[' 1 -eq 0 ']'
+ echo 'number 7 is odd'
Current Result: test1.csv gives me the following result:
,59a,b,c,d,e,f
,59a,b,c,d,e,f
,59a,b,c,d,e,f
,59a,b,c,d,e,f
,59a,b,c,d,e,f
,59a,b,c,d,e,f
,59a,b,c,d,e,f
a,b,c,d,e,f,59
Problem 1: The id is always the same.
Problem 2: The id does not get incremented but seems to only display the last one calculated.
Does anyone has an idea what could be possibly wrong please?
Upvotes: 1
Views: 86
Reputation: 8406
Using GNU seq
, paste
, wc
, and some shell arithmetic with a
bit of fudging to make up for floating point round-off error:
n=35; seq -f '%.0f' $n.9 .5 $(($n + $(wc -l < test.csv)/2 )).5 |
paste -d , test.csv -
Using jot
, paste
, & wc
:
n=36 p=$(wc -l < test.csv) ; jot $p $n $((p+n)) .499999999 |
paste -d , test.csv -
Output of either:
a,b,c,d,e,f,36
a,b,c,d,e,f,36
a,b,c,d,e,f,37
a,b,c,d,e,f,37
a,b,c,d,e,f,38
a,b,c,d,e,f,38
a,b,c,d,e,f,39
a,b,c,d,e,f,39
Upvotes: 0
Reputation: 58400
This might work for you (GNU sed):
var=36
sed '1{x;s/^/'$var'/;x}; # prime the counter
1~2,+1{G;s/\n/,/}; # append the counter
2~2{x;s/.*/expr & + 1/e;x}' file # increment the counter
The address range 1~2,+1
means 1 step 2 plus 1 or every two lines starting at line 1.
The address 2~2
means 2 step 2 or every second line starting at 2.
The RHS of the last substitution uses the command expr
to increment the stored variable by means of the e
flag which evaluates the expression.
Upvotes: 1
Reputation: 133508
Could you please try following.
val="35" ##shell variable.
awk -v var="$val" 'BEGIN{FS=OFS=","} FNR%2!=0{++var} {$(NF+1)=var} 1' Input_file
Explanation: Adding detailed explanation for above.
awk -v var="$val" ' ##Starting awk program from here and creating awk variable var which has val in it.
BEGIN{ ##Starting BEGIN section of awk program from here.
FS=OFS="," ##Setting field and output field separator as comma here.
}
FNR%2!=0{ ##Checking condition if line is odd line number wise then do following.
++var ##increase value of var with 1 here.
}
{
$(NF+1)=var ##Adding 1 more field which has var field in it for current line.
}
1 ##1 will print current line here.
' Input_file ##Mentioning Input_file name here.
Upvotes: 3
Reputation: 141000
It's typicall to use awk
to parse files:
awk '{print $0 "," 36+int((NR-1)/2)}'
NR
- current line number, starts with 1
(NR-1)/2
- calculate number from current line number. So a sequence of numbers like: {0, 0.5, 1, 1.5, 2, 2.5, ....etc.}
for each line numberint(...)
- round down to integers36+
you wanted to start with 36
$0
current line","
add a comma between the number and current lineNotes:
sed -e "s/$/,$g/" test.csv > test1.csv
is overwriting the same file over and over again for each loopif ((j <= lines)); then
for clearer code.Upvotes: 4