How to move the last [0-9]{1,9} cellvalue of a line into the last row (.csv) with bash

example .csv:

"something","31","null","null","null","null",
"something","something","something","142","null","null",
"something","something","24","null","null","null",

I wish to have this result:

"something","null","null","null","null","31",
"something","something","something","null","null","142",
"something","something","null","null","null","24",

How do i move the last [0-9]{1,9} number value with a bash-script into the last cell (if there are only null values in the cells after)?

I tried to do it with sed, but no luck.

Upvotes: 0

Views: 86

Answers (2)

Ivan
Ivan

Reputation: 7277

Here is my variant in bash with explanation

raw=( $(cat file) )         # load data to raw array
for item in "${raw[@]}"; {  # loop through raw data
    search=${item//[!0-9]/} # this will give only digits
    # if match found remove it from string by change ,"123", to a comma and paste to the end
    [[ $search ]] && item="${item//,\"$search\",/,}\"$search\"," 
    echo $item # print result
}

Upvotes: 1

Kent
Kent

Reputation: 195059

This short awk script works for the given example:

awk -F',' -v OFS=',' -v pat='^"[0-9]+"$' '{
for(i=NF;i>0;i--)if($i~ pat ){$NF=$i FS;$i="\x98";break}
    sub("\x98,","")
}7' file

short explanation:

This is an interesting problem.

  • the pat variable stores the regex pattern we want to move to the end
  • for each line, we do a loop from the end and check the pattern, so that we can make sure we find the last matched col.
  • if we found the col, we set the last field with the matched column with comma. (I noticed you have always an empty field at the end of each row). And we set the value of the col with an invisible value \x98 so that we can later easily to remove.
  • finally, we remove the "\x98," by the sub()

test

kent$  cat f
"something","31","null","null","null","null",
"something","something","something","142","null","null",
"something","something","24","null","null","null",

kent$  awk -F',' -v OFS=',' -v pat='^"[0-9]+"$' '{
for(i=NF;i>0;i--)if($i~ pat ){$NF=$i FS;$i="\x98";break}
        sub("\x98,","")
}7' f 
"something","null","null","null","null","31",
"something","something","something","null","null","142",
"something","something","null","null","null","24",

Upvotes: 1

Related Questions