Move specific column from csv file in front (select column by name)
Consider this data:
#!/usr/bin/env bash
cat > example_file.txt <<EOL
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
2, 4.1, 9.2
2, 4.2, 2.11
EOL
I want to move the 'value' column in front:
value, price, group
3.21, 3.21, 1
3.42, 4.11, 1
3.5, 1.22, 1
4.1, 9.2, 2
4.2, 2.11, 2
the problem is: the order of the column (or even the number of column or the name of many of those columns --except 'value' which is always there) varies from file to file. So I have to select the value column by name (not order).
How can I do this?
command-line bash text-processing csv
add a comment |
Consider this data:
#!/usr/bin/env bash
cat > example_file.txt <<EOL
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
2, 4.1, 9.2
2, 4.2, 2.11
EOL
I want to move the 'value' column in front:
value, price, group
3.21, 3.21, 1
3.42, 4.11, 1
3.5, 1.22, 1
4.1, 9.2, 2
4.2, 2.11, 2
the problem is: the order of the column (or even the number of column or the name of many of those columns --except 'value' which is always there) varies from file to file. So I have to select the value column by name (not order).
How can I do this?
command-line bash text-processing csv
Do you need to output the additional columns - or justvalue,price,groupin that order regardless of what other columns may exist?
– steeldriver
Jan 15 at 0:54
all the original columns but with value now moved to being the first one
– user2413
Jan 15 at 0:58
add a comment |
Consider this data:
#!/usr/bin/env bash
cat > example_file.txt <<EOL
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
2, 4.1, 9.2
2, 4.2, 2.11
EOL
I want to move the 'value' column in front:
value, price, group
3.21, 3.21, 1
3.42, 4.11, 1
3.5, 1.22, 1
4.1, 9.2, 2
4.2, 2.11, 2
the problem is: the order of the column (or even the number of column or the name of many of those columns --except 'value' which is always there) varies from file to file. So I have to select the value column by name (not order).
How can I do this?
command-line bash text-processing csv
Consider this data:
#!/usr/bin/env bash
cat > example_file.txt <<EOL
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
2, 4.1, 9.2
2, 4.2, 2.11
EOL
I want to move the 'value' column in front:
value, price, group
3.21, 3.21, 1
3.42, 4.11, 1
3.5, 1.22, 1
4.1, 9.2, 2
4.2, 2.11, 2
the problem is: the order of the column (or even the number of column or the name of many of those columns --except 'value' which is always there) varies from file to file. So I have to select the value column by name (not order).
How can I do this?
command-line bash text-processing csv
command-line bash text-processing csv
edited Jan 21 at 11:20
Olorin
2,141720
2,141720
asked Jan 15 at 0:35
user2413user2413
3,931133962
3,931133962
Do you need to output the additional columns - or justvalue,price,groupin that order regardless of what other columns may exist?
– steeldriver
Jan 15 at 0:54
all the original columns but with value now moved to being the first one
– user2413
Jan 15 at 0:58
add a comment |
Do you need to output the additional columns - or justvalue,price,groupin that order regardless of what other columns may exist?
– steeldriver
Jan 15 at 0:54
all the original columns but with value now moved to being the first one
– user2413
Jan 15 at 0:58
Do you need to output the additional columns - or just
value,price,group in that order regardless of what other columns may exist?– steeldriver
Jan 15 at 0:54
Do you need to output the additional columns - or just
value,price,group in that order regardless of what other columns may exist?– steeldriver
Jan 15 at 0:54
all the original columns but with value now moved to being the first one
– user2413
Jan 15 at 0:58
all the original columns but with value now moved to being the first one
– user2413
Jan 15 at 0:58
add a comment |
3 Answers
3
active
oldest
votes
If you don't mind the value column being duplicated, you could do something like this, with csvtool:
$ csvtool paste <(csvtool namedcol value example_file.txt) example_file.txt
value,group,value,price
3.21,1,3.21,3.21
3.42,1,3.42,4.11
3.5,1,3.5,1.22
4.1,2,4.1,9.2
4.2,2,4.2,2.11
However as far as I know csvtool won't move (or remove) a namedcol.
If you can't find a specialized CSV tool that will, you can roll your own using a general purpose language such as Awk or Perl. The idea would be to search the fields of the first row for the index of the matching column, then slice and dice the fields in the chosen order.
For example using the perl Text::CSV module, and this trick How to get the index of specific element (value) of an array?
$ perl -MText::CSV -lpe '
BEGIN{ $p = Text::CSV->new({ allow_whitespace => 1 }) };
@f = $p->fields() if $p->parse($_);
($i) = grep { $f[$_] eq "value" } (0..$#f) if $. == 1;
$_ = join ", ", splice(@f, $i, 1), @f
' example_file.txt
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
4.1, 2, 9.2
4.2, 2, 2.11
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
1
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
add a comment |
With the great Miller (http://johnkerl.org/miller/doc) is very easy
mlr --csv reorder -f " value, price,group" input.csv
you have
value, price,group
3.21, 3.21,1
3.42, 4.11,1
3.5, 1.22,1
4.1, 9.2,2
4.2, 2.11,2
Please note: I have edited my command, taking into account the spaces in fields name of the question CSV
2
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
I looked at both, butmlraka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.
– zx485
Jan 20 at 22:43
1
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
1
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
|
show 8 more comments
My suggestion is the following script:
#!/bin/bash
# Set a default value of the LABEL of the target column that must become first column
if [[ -z ${LABEL+x} ]]; then LABEL='value'; fi
# Process a single FILE
move_the_label_column_first() {
# Read the LABELS on the first line of the input file as an array
IFS=', ' read -a LABELS < <(cat "$FILE" 2>/dev/null | head -n1)
# Find the number of the target column
for ((COL = 0; COL < ${#LABELS[@]}; ++COL))
do
if [[ ${LABELS[$COL]} == "$LABEL" ]]
then
break
fi
done
# Read each LINE from the input file as an array and output it in the new order
while IFS=', ' read -a LINE
do
printf '%s, ' "${LINE[$COL]}" "${LINE[@]:0:$COL}" "${LINE[@]:$((COL + 1))}" |
sed 's/, $/n/'
done < <(cat "$FILE" 2>/dev/null)
}
# Process all input files, exclude the current script filename
for FILE in "$@"
do
if [[ -f $FILE ]] && [[ $FILE != $(basename "$0") ]]
then
#echo "Input file: $FILE"
move_the_label_column_first
fi
done
Let's call the script reorder.sh. To illustrate the script's capabilities let's assume there are the following files we want to process and they are located in the same directory where our script is.
$ cat in-file-1
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
$ cat in-file-2
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process one input file:
$ ./reorder.sh in-file-1
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
Process two input files and change the label of the column that must become first column to price:
$ LABEL='price' ./reorder.sh in-file-1 in-file-2
price, group, value
3.21, 1, 3.21
4.11, 1, 3.42
1.22, 1, 3.5
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process all files in the directory:
$ ./reorder.sh *
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
value, price, group, other
3.21, 3.21, 1, 7
3.42, 4.11, 1, 13
3.5, 1.22, 1, -1
Process recursively:
$ shopt -s globstar
$ ./reorder.sh **/*
value, group, price
3.21, 1, 3.21
...
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1109777%2fmove-specific-column-from-csv-file-in-front-select-column-by-name%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you don't mind the value column being duplicated, you could do something like this, with csvtool:
$ csvtool paste <(csvtool namedcol value example_file.txt) example_file.txt
value,group,value,price
3.21,1,3.21,3.21
3.42,1,3.42,4.11
3.5,1,3.5,1.22
4.1,2,4.1,9.2
4.2,2,4.2,2.11
However as far as I know csvtool won't move (or remove) a namedcol.
If you can't find a specialized CSV tool that will, you can roll your own using a general purpose language such as Awk or Perl. The idea would be to search the fields of the first row for the index of the matching column, then slice and dice the fields in the chosen order.
For example using the perl Text::CSV module, and this trick How to get the index of specific element (value) of an array?
$ perl -MText::CSV -lpe '
BEGIN{ $p = Text::CSV->new({ allow_whitespace => 1 }) };
@f = $p->fields() if $p->parse($_);
($i) = grep { $f[$_] eq "value" } (0..$#f) if $. == 1;
$_ = join ", ", splice(@f, $i, 1), @f
' example_file.txt
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
4.1, 2, 9.2
4.2, 2, 2.11
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
1
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
add a comment |
If you don't mind the value column being duplicated, you could do something like this, with csvtool:
$ csvtool paste <(csvtool namedcol value example_file.txt) example_file.txt
value,group,value,price
3.21,1,3.21,3.21
3.42,1,3.42,4.11
3.5,1,3.5,1.22
4.1,2,4.1,9.2
4.2,2,4.2,2.11
However as far as I know csvtool won't move (or remove) a namedcol.
If you can't find a specialized CSV tool that will, you can roll your own using a general purpose language such as Awk or Perl. The idea would be to search the fields of the first row for the index of the matching column, then slice and dice the fields in the chosen order.
For example using the perl Text::CSV module, and this trick How to get the index of specific element (value) of an array?
$ perl -MText::CSV -lpe '
BEGIN{ $p = Text::CSV->new({ allow_whitespace => 1 }) };
@f = $p->fields() if $p->parse($_);
($i) = grep { $f[$_] eq "value" } (0..$#f) if $. == 1;
$_ = join ", ", splice(@f, $i, 1), @f
' example_file.txt
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
4.1, 2, 9.2
4.2, 2, 2.11
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
1
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
add a comment |
If you don't mind the value column being duplicated, you could do something like this, with csvtool:
$ csvtool paste <(csvtool namedcol value example_file.txt) example_file.txt
value,group,value,price
3.21,1,3.21,3.21
3.42,1,3.42,4.11
3.5,1,3.5,1.22
4.1,2,4.1,9.2
4.2,2,4.2,2.11
However as far as I know csvtool won't move (or remove) a namedcol.
If you can't find a specialized CSV tool that will, you can roll your own using a general purpose language such as Awk or Perl. The idea would be to search the fields of the first row for the index of the matching column, then slice and dice the fields in the chosen order.
For example using the perl Text::CSV module, and this trick How to get the index of specific element (value) of an array?
$ perl -MText::CSV -lpe '
BEGIN{ $p = Text::CSV->new({ allow_whitespace => 1 }) };
@f = $p->fields() if $p->parse($_);
($i) = grep { $f[$_] eq "value" } (0..$#f) if $. == 1;
$_ = join ", ", splice(@f, $i, 1), @f
' example_file.txt
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
4.1, 2, 9.2
4.2, 2, 2.11
If you don't mind the value column being duplicated, you could do something like this, with csvtool:
$ csvtool paste <(csvtool namedcol value example_file.txt) example_file.txt
value,group,value,price
3.21,1,3.21,3.21
3.42,1,3.42,4.11
3.5,1,3.5,1.22
4.1,2,4.1,9.2
4.2,2,4.2,2.11
However as far as I know csvtool won't move (or remove) a namedcol.
If you can't find a specialized CSV tool that will, you can roll your own using a general purpose language such as Awk or Perl. The idea would be to search the fields of the first row for the index of the matching column, then slice and dice the fields in the chosen order.
For example using the perl Text::CSV module, and this trick How to get the index of specific element (value) of an array?
$ perl -MText::CSV -lpe '
BEGIN{ $p = Text::CSV->new({ allow_whitespace => 1 }) };
@f = $p->fields() if $p->parse($_);
($i) = grep { $f[$_] eq "value" } (0..$#f) if $. == 1;
$_ = join ", ", splice(@f, $i, 1), @f
' example_file.txt
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
4.1, 2, 9.2
4.2, 2, 2.11
edited Jan 15 at 2:26
answered Jan 15 at 2:03
steeldriversteeldriver
67.3k11109181
67.3k11109181
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
1
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
add a comment |
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
1
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
Fantastic! I will throw a bounty your way to attract attention to this great answer asap
– user2413
Jan 15 at 2:12
1
1
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
Thank you for your answer. I now find aborruso's answer the simplest to use for this problem.
– user2413
Jan 21 at 13:24
add a comment |
With the great Miller (http://johnkerl.org/miller/doc) is very easy
mlr --csv reorder -f " value, price,group" input.csv
you have
value, price,group
3.21, 3.21,1
3.42, 4.11,1
3.5, 1.22,1
4.1, 9.2,2
4.2, 2.11,2
Please note: I have edited my command, taking into account the spaces in fields name of the question CSV
2
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
I looked at both, butmlraka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.
– zx485
Jan 20 at 22:43
1
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
1
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
|
show 8 more comments
With the great Miller (http://johnkerl.org/miller/doc) is very easy
mlr --csv reorder -f " value, price,group" input.csv
you have
value, price,group
3.21, 3.21,1
3.42, 4.11,1
3.5, 1.22,1
4.1, 9.2,2
4.2, 2.11,2
Please note: I have edited my command, taking into account the spaces in fields name of the question CSV
2
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
I looked at both, butmlraka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.
– zx485
Jan 20 at 22:43
1
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
1
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
|
show 8 more comments
With the great Miller (http://johnkerl.org/miller/doc) is very easy
mlr --csv reorder -f " value, price,group" input.csv
you have
value, price,group
3.21, 3.21,1
3.42, 4.11,1
3.5, 1.22,1
4.1, 9.2,2
4.2, 2.11,2
Please note: I have edited my command, taking into account the spaces in fields name of the question CSV
With the great Miller (http://johnkerl.org/miller/doc) is very easy
mlr --csv reorder -f " value, price,group" input.csv
you have
value, price,group
3.21, 3.21,1
3.42, 4.11,1
3.5, 1.22,1
4.1, 9.2,2
4.2, 2.11,2
Please note: I have edited my command, taking into account the spaces in fields name of the question CSV
edited Jan 21 at 15:31
answered Jan 20 at 21:02
aborrusoaborruso
1714
1714
2
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
I looked at both, butmlraka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.
– zx485
Jan 20 at 22:43
1
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
1
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
|
show 8 more comments
2
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
I looked at both, butmlraka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.
– zx485
Jan 20 at 22:43
1
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
1
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
2
2
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
I would like to upvote your answer because of its simplicity, but it does not work...The output I get is identical to the input :-(
– zx485
Jan 20 at 22:29
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
hi @zx485 I'm using this csv gist.githubusercontent.com/aborruso/… Please look also at this video youtu.be/XcTXaxKy-t4?hd=1
– aborruso
Jan 20 at 22:39
I looked at both, but
mlr aka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.– zx485
Jan 20 at 22:43
I looked at both, but
mlr aka miller still doesn't do what it's supposed to do. I got it from the repositories of Ubuntu 18.04.– zx485
Jan 20 at 22:43
1
1
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
You are welcome @zx485! But why nasty? As you can read in CSV RFC " Spaces are considered part of a field and should not be ignored": than it's necessary to take in account spaces in field name.
– aborruso
Jan 21 at 15:26
1
1
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
Well then. I didn't knew that. Thanks for the clarification.
– zx485
Jan 21 at 15:35
|
show 8 more comments
My suggestion is the following script:
#!/bin/bash
# Set a default value of the LABEL of the target column that must become first column
if [[ -z ${LABEL+x} ]]; then LABEL='value'; fi
# Process a single FILE
move_the_label_column_first() {
# Read the LABELS on the first line of the input file as an array
IFS=', ' read -a LABELS < <(cat "$FILE" 2>/dev/null | head -n1)
# Find the number of the target column
for ((COL = 0; COL < ${#LABELS[@]}; ++COL))
do
if [[ ${LABELS[$COL]} == "$LABEL" ]]
then
break
fi
done
# Read each LINE from the input file as an array and output it in the new order
while IFS=', ' read -a LINE
do
printf '%s, ' "${LINE[$COL]}" "${LINE[@]:0:$COL}" "${LINE[@]:$((COL + 1))}" |
sed 's/, $/n/'
done < <(cat "$FILE" 2>/dev/null)
}
# Process all input files, exclude the current script filename
for FILE in "$@"
do
if [[ -f $FILE ]] && [[ $FILE != $(basename "$0") ]]
then
#echo "Input file: $FILE"
move_the_label_column_first
fi
done
Let's call the script reorder.sh. To illustrate the script's capabilities let's assume there are the following files we want to process and they are located in the same directory where our script is.
$ cat in-file-1
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
$ cat in-file-2
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process one input file:
$ ./reorder.sh in-file-1
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
Process two input files and change the label of the column that must become first column to price:
$ LABEL='price' ./reorder.sh in-file-1 in-file-2
price, group, value
3.21, 1, 3.21
4.11, 1, 3.42
1.22, 1, 3.5
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process all files in the directory:
$ ./reorder.sh *
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
value, price, group, other
3.21, 3.21, 1, 7
3.42, 4.11, 1, 13
3.5, 1.22, 1, -1
Process recursively:
$ shopt -s globstar
$ ./reorder.sh **/*
value, group, price
3.21, 1, 3.21
...
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
add a comment |
My suggestion is the following script:
#!/bin/bash
# Set a default value of the LABEL of the target column that must become first column
if [[ -z ${LABEL+x} ]]; then LABEL='value'; fi
# Process a single FILE
move_the_label_column_first() {
# Read the LABELS on the first line of the input file as an array
IFS=', ' read -a LABELS < <(cat "$FILE" 2>/dev/null | head -n1)
# Find the number of the target column
for ((COL = 0; COL < ${#LABELS[@]}; ++COL))
do
if [[ ${LABELS[$COL]} == "$LABEL" ]]
then
break
fi
done
# Read each LINE from the input file as an array and output it in the new order
while IFS=', ' read -a LINE
do
printf '%s, ' "${LINE[$COL]}" "${LINE[@]:0:$COL}" "${LINE[@]:$((COL + 1))}" |
sed 's/, $/n/'
done < <(cat "$FILE" 2>/dev/null)
}
# Process all input files, exclude the current script filename
for FILE in "$@"
do
if [[ -f $FILE ]] && [[ $FILE != $(basename "$0") ]]
then
#echo "Input file: $FILE"
move_the_label_column_first
fi
done
Let's call the script reorder.sh. To illustrate the script's capabilities let's assume there are the following files we want to process and they are located in the same directory where our script is.
$ cat in-file-1
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
$ cat in-file-2
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process one input file:
$ ./reorder.sh in-file-1
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
Process two input files and change the label of the column that must become first column to price:
$ LABEL='price' ./reorder.sh in-file-1 in-file-2
price, group, value
3.21, 1, 3.21
4.11, 1, 3.42
1.22, 1, 3.5
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process all files in the directory:
$ ./reorder.sh *
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
value, price, group, other
3.21, 3.21, 1, 7
3.42, 4.11, 1, 13
3.5, 1.22, 1, -1
Process recursively:
$ shopt -s globstar
$ ./reorder.sh **/*
value, group, price
3.21, 1, 3.21
...
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
add a comment |
My suggestion is the following script:
#!/bin/bash
# Set a default value of the LABEL of the target column that must become first column
if [[ -z ${LABEL+x} ]]; then LABEL='value'; fi
# Process a single FILE
move_the_label_column_first() {
# Read the LABELS on the first line of the input file as an array
IFS=', ' read -a LABELS < <(cat "$FILE" 2>/dev/null | head -n1)
# Find the number of the target column
for ((COL = 0; COL < ${#LABELS[@]}; ++COL))
do
if [[ ${LABELS[$COL]} == "$LABEL" ]]
then
break
fi
done
# Read each LINE from the input file as an array and output it in the new order
while IFS=', ' read -a LINE
do
printf '%s, ' "${LINE[$COL]}" "${LINE[@]:0:$COL}" "${LINE[@]:$((COL + 1))}" |
sed 's/, $/n/'
done < <(cat "$FILE" 2>/dev/null)
}
# Process all input files, exclude the current script filename
for FILE in "$@"
do
if [[ -f $FILE ]] && [[ $FILE != $(basename "$0") ]]
then
#echo "Input file: $FILE"
move_the_label_column_first
fi
done
Let's call the script reorder.sh. To illustrate the script's capabilities let's assume there are the following files we want to process and they are located in the same directory where our script is.
$ cat in-file-1
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
$ cat in-file-2
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process one input file:
$ ./reorder.sh in-file-1
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
Process two input files and change the label of the column that must become first column to price:
$ LABEL='price' ./reorder.sh in-file-1 in-file-2
price, group, value
3.21, 1, 3.21
4.11, 1, 3.42
1.22, 1, 3.5
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process all files in the directory:
$ ./reorder.sh *
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
value, price, group, other
3.21, 3.21, 1, 7
3.42, 4.11, 1, 13
3.5, 1.22, 1, -1
Process recursively:
$ shopt -s globstar
$ ./reorder.sh **/*
value, group, price
3.21, 1, 3.21
...
My suggestion is the following script:
#!/bin/bash
# Set a default value of the LABEL of the target column that must become first column
if [[ -z ${LABEL+x} ]]; then LABEL='value'; fi
# Process a single FILE
move_the_label_column_first() {
# Read the LABELS on the first line of the input file as an array
IFS=', ' read -a LABELS < <(cat "$FILE" 2>/dev/null | head -n1)
# Find the number of the target column
for ((COL = 0; COL < ${#LABELS[@]}; ++COL))
do
if [[ ${LABELS[$COL]} == "$LABEL" ]]
then
break
fi
done
# Read each LINE from the input file as an array and output it in the new order
while IFS=', ' read -a LINE
do
printf '%s, ' "${LINE[$COL]}" "${LINE[@]:0:$COL}" "${LINE[@]:$((COL + 1))}" |
sed 's/, $/n/'
done < <(cat "$FILE" 2>/dev/null)
}
# Process all input files, exclude the current script filename
for FILE in "$@"
do
if [[ -f $FILE ]] && [[ $FILE != $(basename "$0") ]]
then
#echo "Input file: $FILE"
move_the_label_column_first
fi
done
Let's call the script reorder.sh. To illustrate the script's capabilities let's assume there are the following files we want to process and they are located in the same directory where our script is.
$ cat in-file-1
group, value, price
1, 3.21, 3.21
1, 3.42, 4.11
1, 3.5, 1.22
$ cat in-file-2
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process one input file:
$ ./reorder.sh in-file-1
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
Process two input files and change the label of the column that must become first column to price:
$ LABEL='price' ./reorder.sh in-file-1 in-file-2
price, group, value
3.21, 1, 3.21
4.11, 1, 3.42
1.22, 1, 3.5
price, group, value, other
3.21, 1, 3.21, 7
4.11, 1, 3.42, 13
1.22, 1, 3.5, -1
Process all files in the directory:
$ ./reorder.sh *
value, group, price
3.21, 1, 3.21
3.42, 1, 4.11
3.5, 1, 1.22
value, price, group, other
3.21, 3.21, 1, 7
3.42, 4.11, 1, 13
3.5, 1.22, 1, -1
Process recursively:
$ shopt -s globstar
$ ./reorder.sh **/*
value, group, price
3.21, 1, 3.21
...
edited Jan 21 at 19:20
answered Jan 20 at 16:36
pa4080pa4080
14.1k52665
14.1k52665
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
add a comment |
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
Thank you for your answer (+1). I find aborruso's to be the simplest to use in the sense that it all happens 'under the fold'.
– user2413
Jan 21 at 13:26
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
@user2413, thanks. Yes, aborruso's answer looks nice and simple, but I didn't succeed with it. However, my suggestion is most portable of the 4 solutions provided up to this moment :)
– pa4080
Jan 21 at 19:27
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1109777%2fmove-specific-column-from-csv-file-in-front-select-column-by-name%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you need to output the additional columns - or just
value,price,groupin that order regardless of what other columns may exist?– steeldriver
Jan 15 at 0:54
all the original columns but with value now moved to being the first one
– user2413
Jan 15 at 0:58