Suntory
Suntory

Reputation: 351

how to transpose values two by two using shell?

I have my data in a file store by lines like this :

3.172704445659,50.011996744997,3.1821975358417,50.012335988197,3.2174797791605,50.023182479597

And I would like 2 columns :

3.172704445659 50.011996744997
3.1821975358417 50.012335988197
3.2174797791605 50.023182479597

I know sed command for delete ','(sed "s/,/ /") but I don't know how to "back to line" every two digits ?

Do you have any ideas ?

Upvotes: 1

Views: 134

Answers (4)

CJK
CJK

Reputation: 6092

awk and sed are powerful tools, and in fact constitute programming languages in their own right. So, they can, of course, handle this task with ease.

But so can bash, which will have the benefits of being more portable (no outside dependencies), and executing faster (as it uses only built-in functions):

IFS=$', \n'
values=($(</path/to/file))
printf '%.13f %.13f\n' "${values[@]}"

Upvotes: 0

Lars Fischer
Lars Fischer

Reputation: 10169

Since you already tried sed, here is a solution using sed:

sed -r "s/(([^,]*,){2})/\1\n/g; s/,\n/\n/g" YOURFILE
  • -r uses sed extended regexp
  • there are two substitutions used:
    1. the first substitution, with the (([^,]*,){2}) part, captures two comma separated numbers at once and store them into \1 for reuse: \1 holds in your example at the first match: 3.172704445659,50.011996744997,. Notice: both commas are present.
      • (([^,]*,){2}) means capture a sequence consisting of NOT comma - that is the [^,]* part followed by a ,
      • we want two such sequences - that is the (...){2} part
      • and we want to capture it for reuse in \1 - that is the outer pair of parentheses
      • then substitute with \1\n - that just inserts the newline after the match, in other words a newline after each second comma
    2. as we have now a comma before the newline that we need to get rid of, we do a second substitution to achieve that:
      • s/,\n/\n/g
      • a comma followed by newline is replace with only newline - in other words the comma is deleted

Upvotes: 0

user14967413
user14967413

Reputation: 1416

Solution viable for those without knowledge of awk command - simple for loop over an array of numbers.

IFS=',' read -ra NUMBERS < file

NUMBERS_ON_LINE=2
INDEX=0
for NUMBER in "${NUMBERS[@]}"; do
  if (($INDEX==$NUMBERS_ON_LINE-1)); then
    INDEX=0
    echo "$NUMBER"
  else
    ((INDEX++))
    echo -n "$NUMBER "
  fi
done

Upvotes: 0

James Brown
James Brown

Reputation: 37414

One in awk:

$ awk -F, '{for(i=1;i<=NF;i++)printf "%s%s",$i,(i%2&&i!=NF?OFS:ORS)}' file

Output:

3.172704445659 50.011996744997
3.1821975358417 50.012335988197
3.2174797791605 50.023182479597

Upvotes: 1

Related Questions