Removing numeric values in certain columns whilst keeping minus signs? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) 2019 Community Moderator Election Results Why I closed the “Why is Kali so hard” questionHow to remove an apostrophe ( ' ) from couple of columns of a .CSV file?How to use awk or sed to convert csv diffs into more readable formatGrep rest of line…after matchNeed to remove - (Minus) sign at the end in number from many columns and insert it on columns removedChanging the sign (+ or -) of a number based on non-matching columnsHow to take the values from two columns in a txt file and match them to values in anotherawk help for printing from a particular column till the endRemove the multiple comma's from specific column of tab delimited fileand print the words on new lineRemove the line if a field of the line exists in another filetext processing - Extracting using cshell and awk
Can an alien society believe that their star system is the universe?
What does "lightly crushed" mean for cardamon pods?
Is safe to use va_start macro with this as parameter?
2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?
Is there any way for the UK Prime Minister to make a motion directly dependent on Government confidence?
Around usage results
Fantasy story; one type of magic grows in power with use, but the more powerful they are, they more they are drawn to travel to their source
Can a new player join a group only when a new campaign starts?
Why aren't air breathing engines used as small first stages
Trademark violation for app?
Quick way to create a symlink?
Is it common practice to audition new musicians 1-2-1 before rehearsing with the entire band?
Did MS DOS itself ever use blinking text?
What would be the ideal power source for a cybernetic eye?
Has negative voting ever been officially implemented in elections, or seriously proposed, or even studied?
How do I stop a creek from eroding my steep embankment?
What are the out-of-universe reasons for the references to Toby Maguire-era Spider-Man in ITSV
What is the meaning of the simile “quick as silk”?
Irreducible of finite Krull dimension implies quasi-compact?
How to answer "Have you ever been terminated?"
What is this building called? (It was built in 2002)
For a new assistant professor in CS, how to build/manage a publication pipeline
Maximum summed powersets with non-adjacent items
Why didn't Eitri join the fight?
Removing numeric values in certain columns whilst keeping minus signs?
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionHow to remove an apostrophe ( ' ) from couple of columns of a .CSV file?How to use awk or sed to convert csv diffs into more readable formatGrep rest of line…after matchNeed to remove - (Minus) sign at the end in number from many columns and insert it on columns removedChanging the sign (+ or -) of a number based on non-matching columnsHow to take the values from two columns in a txt file and match them to values in anotherawk help for printing from a particular column till the endRemove the multiple comma's from specific column of tab delimited fileand print the words on new lineRemove the line if a field of the line exists in another filetext processing - Extracting using cshell and awk
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have the following data frame that continues indefinitely horizontally and vertically with negative numbers only in the odd columns:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
And I want the 2nd, 4th and 6th complete columns (or every even column) and the minus signs only from the 1st, 3rd, and 5th (or every odd column), so I get this:
- 2 4 - 9
3 - 5 - 11
And eventually end up with this:
-2 4 -9
3 -5 -11
So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it.
Is there a way to do this with awk/sed?
This is about a far as I get:
awk ' for (i=2;i<=NF;i+=2) $i="" 1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing sed awk
add a comment |
I have the following data frame that continues indefinitely horizontally and vertically with negative numbers only in the odd columns:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
And I want the 2nd, 4th and 6th complete columns (or every even column) and the minus signs only from the 1st, 3rd, and 5th (or every odd column), so I get this:
- 2 4 - 9
3 - 5 - 11
And eventually end up with this:
-2 4 -9
3 -5 -11
So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it.
Is there a way to do this with awk/sed?
This is about a far as I get:
awk ' for (i=2;i<=NF;i+=2) $i="" 1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing sed awk
When you say your dataframe continues indefinitely, do you mean horizontally or vertically? How many columns do you actually have?
– terdon♦
Jun 21 '15 at 14:36
Both. My test data is 3 rows by 3 columns but the actual data has varying numbers, I'd say up 40 rows and 40 columns.
– Asfound
Jun 21 '15 at 14:41
add a comment |
I have the following data frame that continues indefinitely horizontally and vertically with negative numbers only in the odd columns:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
And I want the 2nd, 4th and 6th complete columns (or every even column) and the minus signs only from the 1st, 3rd, and 5th (or every odd column), so I get this:
- 2 4 - 9
3 - 5 - 11
And eventually end up with this:
-2 4 -9
3 -5 -11
So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it.
Is there a way to do this with awk/sed?
This is about a far as I get:
awk ' for (i=2;i<=NF;i+=2) $i="" 1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing sed awk
I have the following data frame that continues indefinitely horizontally and vertically with negative numbers only in the odd columns:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
And I want the 2nd, 4th and 6th complete columns (or every even column) and the minus signs only from the 1st, 3rd, and 5th (or every odd column), so I get this:
- 2 4 - 9
3 - 5 - 11
And eventually end up with this:
-2 4 -9
3 -5 -11
So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it.
Is there a way to do this with awk/sed?
This is about a far as I get:
awk ' for (i=2;i<=NF;i+=2) $i="" 1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing sed awk
text-processing sed awk
edited Apr 13 at 15:23
Rui F Ribeiro
42.1k1484142
42.1k1484142
asked Jun 21 '15 at 13:31
AsfoundAsfound
6717
6717
When you say your dataframe continues indefinitely, do you mean horizontally or vertically? How many columns do you actually have?
– terdon♦
Jun 21 '15 at 14:36
Both. My test data is 3 rows by 3 columns but the actual data has varying numbers, I'd say up 40 rows and 40 columns.
– Asfound
Jun 21 '15 at 14:41
add a comment |
When you say your dataframe continues indefinitely, do you mean horizontally or vertically? How many columns do you actually have?
– terdon♦
Jun 21 '15 at 14:36
Both. My test data is 3 rows by 3 columns but the actual data has varying numbers, I'd say up 40 rows and 40 columns.
– Asfound
Jun 21 '15 at 14:41
When you say your dataframe continues indefinitely, do you mean horizontally or vertically? How many columns do you actually have?
– terdon♦
Jun 21 '15 at 14:36
When you say your dataframe continues indefinitely, do you mean horizontally or vertically? How many columns do you actually have?
– terdon♦
Jun 21 '15 at 14:36
Both. My test data is 3 rows by 3 columns but the actual data has varying numbers, I'd say up 40 rows and 40 columns.
– Asfound
Jun 21 '15 at 14:41
Both. My test data is 3 rows by 3 columns but the actual data has varying numbers, I'd say up 40 rows and 40 columns.
– Asfound
Jun 21 '15 at 14:41
add a comment |
7 Answers
7
active
oldest
votes
Here's one way:
$ awk 'for(i=1;i<=NF;i+=2)if($i<0)$i="-"else$i=""; ;1' file |
sed 's/- */-/g; s/ */ /g'
-2 4 -9
3 -5 -11
The awk script goes over all odd columns and sets their value to - if they are negative and empty if not. Then, the sed removes any spaces following a - and then replaces multiple consecutive spaces with a single one. Note that this means that the alignment will be broken since some fields will have two characters or more and others will have one. That won't be an issue if you're working with fields, they just don't look pretty.
add a comment |
The sed way:
sed -E '
s/^(([ t]*-?[ t]*[0-9.]+[ t]+[0-9.]+)*)[ t]+-?[ t]*[0-9.]+$/1/;
s/[0-9.]+[ t]+([0-9.]+)/1/g'
Output:
-2 4 -9
3 -5 -11
The first expression kills the trailing column if there are an odd number of columns. It does that by looking for 0 or more pairs <number> <number>, where the first number can be negative.
Edit: A shorter sed solution, inspired by @mikeserv:
sed -E '
s/[0-9.]+[ t]*([0-9.]*)/1/g;
s/[- t]*$//'
The same thing with perl:
perl -lpe 's/^((s*-?s*[d.]+s*[d.]+)*)s+-?s*[d.]+$/$1/o; s/[d.]+s+([d.]+)/$1/g'
Another way with perl (probably the cleanest one):
perl -lpe '$a = 1; s/([d.]+s*)/$a++ % 2 ? "" : $1/eg; s/[-s]*$//o'
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
|
show 4 more comments
A perl one:
$ perl -anle 'BEGIN$,=" "
print map$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"grep!($_%2)0..$#F' file
-2 4 -9
3 -5 -11
-ansplit input to@FarrayBEGIN$,=" "set output field separator to a spacegrep!($_%2)0..$#Fget all even indexes in@Farray, which are indexes of odd elementsmap$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"check if odd element start with-, then append-to next even element, else append a space
add a comment |
As @terdon's answer but without the sed:
awk ' for(i=1;i<=NF;i+=2)
if ($i<0) $(i+1)*=-1;
$i = "";
print
'
add a comment |
A python solution
python -c 'from __future__ import print_function;
import sys, math;
for line in sys.stdin:
x = [int(y) for y in line.split()]
print(*[int(math.copysign(b, a)) for a, b in zip(x[::2], x[1::2])], sep=" ")
' <file
add a comment |
A simple mathematics-based awk solution:
$ cat <<M | awk 'for(i=2;i<=NF;i+=2)printf "%4s",($(i-1)<0?-1:1)*$iprint ""'
-1 2 3 4 -5 9
2 3.2 -4 5 -6
M
-2 4 -9
3.2 -5
- Loop from the second (
i=2) to the last field (i<=NF). - Multiply the previous field (
$(i-1)) with either -1 or 1. - Format the output nicely (
printf "%4s"), and print a trailing newline (print "").
The only caveat to this is that if you have an odd number of columns, the last field will not display anything at all. I hope this is what you expect. Apparently this is what you expect. :)
(edited to work with decimal values, and to make the loop conditions more aligned with the question while saving 2 characters.)
add a comment |
You need to forget the negative entirely - leave it out. You want to consolidate two fields - from left to right. That's very easy.
sed ' s/ *(.*)/1 /
s/([0-9]* *)2/1/g
s/[ -]*$//
' <<IN
-1 2 3 4 -5 9
2 3 -4 5 -6 11
IN
-2 4 -9
3 -5 -11
Notice how I avoid any reference to the sign at all - when the input is processed the automaton will accept only spaces or numbers because it understands nothing else - all else is ignored completely and will remain in place.
When you specify a numeric repetition interval for a (subexpression), only the last occurrence of that expression is 1 back-referenced. So you can just squeeze - or truncate - a repeat interval that easily. And because we squeeze the repeat behind the sign - if there is one - the second occurrence of that pattern will follow any sign that used to precede the first.
The behavior described above is specified by POSIX for all BRE compliant applications, but very few seds get it right. GNU sed does.
Last, the spaces are just to make the pattern occurrence regular.
Of course, this will never work for you. Or, probably more correctly, it will always work for you, but never return any results. How could it if the pattern is indefinite?
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
|
show 3 more comments
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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%2funix.stackexchange.com%2fquestions%2f211138%2fremoving-numeric-values-in-certain-columns-whilst-keeping-minus-signs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here's one way:
$ awk 'for(i=1;i<=NF;i+=2)if($i<0)$i="-"else$i=""; ;1' file |
sed 's/- */-/g; s/ */ /g'
-2 4 -9
3 -5 -11
The awk script goes over all odd columns and sets their value to - if they are negative and empty if not. Then, the sed removes any spaces following a - and then replaces multiple consecutive spaces with a single one. Note that this means that the alignment will be broken since some fields will have two characters or more and others will have one. That won't be an issue if you're working with fields, they just don't look pretty.
add a comment |
Here's one way:
$ awk 'for(i=1;i<=NF;i+=2)if($i<0)$i="-"else$i=""; ;1' file |
sed 's/- */-/g; s/ */ /g'
-2 4 -9
3 -5 -11
The awk script goes over all odd columns and sets their value to - if they are negative and empty if not. Then, the sed removes any spaces following a - and then replaces multiple consecutive spaces with a single one. Note that this means that the alignment will be broken since some fields will have two characters or more and others will have one. That won't be an issue if you're working with fields, they just don't look pretty.
add a comment |
Here's one way:
$ awk 'for(i=1;i<=NF;i+=2)if($i<0)$i="-"else$i=""; ;1' file |
sed 's/- */-/g; s/ */ /g'
-2 4 -9
3 -5 -11
The awk script goes over all odd columns and sets their value to - if they are negative and empty if not. Then, the sed removes any spaces following a - and then replaces multiple consecutive spaces with a single one. Note that this means that the alignment will be broken since some fields will have two characters or more and others will have one. That won't be an issue if you're working with fields, they just don't look pretty.
Here's one way:
$ awk 'for(i=1;i<=NF;i+=2)if($i<0)$i="-"else$i=""; ;1' file |
sed 's/- */-/g; s/ */ /g'
-2 4 -9
3 -5 -11
The awk script goes over all odd columns and sets their value to - if they are negative and empty if not. Then, the sed removes any spaces following a - and then replaces multiple consecutive spaces with a single one. Note that this means that the alignment will be broken since some fields will have two characters or more and others will have one. That won't be an issue if you're working with fields, they just don't look pretty.
edited Jun 21 '15 at 17:16
cuonglm
106k25211309
106k25211309
answered Jun 21 '15 at 14:01
terdon♦terdon
134k33270450
134k33270450
add a comment |
add a comment |
The sed way:
sed -E '
s/^(([ t]*-?[ t]*[0-9.]+[ t]+[0-9.]+)*)[ t]+-?[ t]*[0-9.]+$/1/;
s/[0-9.]+[ t]+([0-9.]+)/1/g'
Output:
-2 4 -9
3 -5 -11
The first expression kills the trailing column if there are an odd number of columns. It does that by looking for 0 or more pairs <number> <number>, where the first number can be negative.
Edit: A shorter sed solution, inspired by @mikeserv:
sed -E '
s/[0-9.]+[ t]*([0-9.]*)/1/g;
s/[- t]*$//'
The same thing with perl:
perl -lpe 's/^((s*-?s*[d.]+s*[d.]+)*)s+-?s*[d.]+$/$1/o; s/[d.]+s+([d.]+)/$1/g'
Another way with perl (probably the cleanest one):
perl -lpe '$a = 1; s/([d.]+s*)/$a++ % 2 ? "" : $1/eg; s/[-s]*$//o'
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
|
show 4 more comments
The sed way:
sed -E '
s/^(([ t]*-?[ t]*[0-9.]+[ t]+[0-9.]+)*)[ t]+-?[ t]*[0-9.]+$/1/;
s/[0-9.]+[ t]+([0-9.]+)/1/g'
Output:
-2 4 -9
3 -5 -11
The first expression kills the trailing column if there are an odd number of columns. It does that by looking for 0 or more pairs <number> <number>, where the first number can be negative.
Edit: A shorter sed solution, inspired by @mikeserv:
sed -E '
s/[0-9.]+[ t]*([0-9.]*)/1/g;
s/[- t]*$//'
The same thing with perl:
perl -lpe 's/^((s*-?s*[d.]+s*[d.]+)*)s+-?s*[d.]+$/$1/o; s/[d.]+s+([d.]+)/$1/g'
Another way with perl (probably the cleanest one):
perl -lpe '$a = 1; s/([d.]+s*)/$a++ % 2 ? "" : $1/eg; s/[-s]*$//o'
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
|
show 4 more comments
The sed way:
sed -E '
s/^(([ t]*-?[ t]*[0-9.]+[ t]+[0-9.]+)*)[ t]+-?[ t]*[0-9.]+$/1/;
s/[0-9.]+[ t]+([0-9.]+)/1/g'
Output:
-2 4 -9
3 -5 -11
The first expression kills the trailing column if there are an odd number of columns. It does that by looking for 0 or more pairs <number> <number>, where the first number can be negative.
Edit: A shorter sed solution, inspired by @mikeserv:
sed -E '
s/[0-9.]+[ t]*([0-9.]*)/1/g;
s/[- t]*$//'
The same thing with perl:
perl -lpe 's/^((s*-?s*[d.]+s*[d.]+)*)s+-?s*[d.]+$/$1/o; s/[d.]+s+([d.]+)/$1/g'
Another way with perl (probably the cleanest one):
perl -lpe '$a = 1; s/([d.]+s*)/$a++ % 2 ? "" : $1/eg; s/[-s]*$//o'
The sed way:
sed -E '
s/^(([ t]*-?[ t]*[0-9.]+[ t]+[0-9.]+)*)[ t]+-?[ t]*[0-9.]+$/1/;
s/[0-9.]+[ t]+([0-9.]+)/1/g'
Output:
-2 4 -9
3 -5 -11
The first expression kills the trailing column if there are an odd number of columns. It does that by looking for 0 or more pairs <number> <number>, where the first number can be negative.
Edit: A shorter sed solution, inspired by @mikeserv:
sed -E '
s/[0-9.]+[ t]*([0-9.]*)/1/g;
s/[- t]*$//'
The same thing with perl:
perl -lpe 's/^((s*-?s*[d.]+s*[d.]+)*)s+-?s*[d.]+$/$1/o; s/[d.]+s+([d.]+)/$1/g'
Another way with perl (probably the cleanest one):
perl -lpe '$a = 1; s/([d.]+s*)/$a++ % 2 ? "" : $1/eg; s/[-s]*$//o'
edited Jun 22 '15 at 20:42
answered Jun 21 '15 at 14:18
lcd047lcd047
5,9261332
5,9261332
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
|
show 4 more comments
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
This works fine on my actual data as long as I add the decimal points into the script. Thanks!
– Asfound
Jun 21 '15 at 14:38
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
@Asfound Ok, I edited my answer to also support decimal points.
– lcd047
Jun 21 '15 at 14:43
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
Hang on, this will fail if there is a negative value as the last (odd) field.
– terdon♦
Jun 21 '15 at 14:47
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
@terdon It fails if there are an odd number of columns, yes. But there are either exactly 6 columns, or "inifinitely many", and "infinitely many" is not an odd number. :)
– lcd047
Jun 21 '15 at 14:50
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
The OP said that there can be "up to 40 columns" :(
– terdon♦
Jun 21 '15 at 14:51
|
show 4 more comments
A perl one:
$ perl -anle 'BEGIN$,=" "
print map$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"grep!($_%2)0..$#F' file
-2 4 -9
3 -5 -11
-ansplit input to@FarrayBEGIN$,=" "set output field separator to a spacegrep!($_%2)0..$#Fget all even indexes in@Farray, which are indexes of odd elementsmap$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"check if odd element start with-, then append-to next even element, else append a space
add a comment |
A perl one:
$ perl -anle 'BEGIN$,=" "
print map$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"grep!($_%2)0..$#F' file
-2 4 -9
3 -5 -11
-ansplit input to@FarrayBEGIN$,=" "set output field separator to a spacegrep!($_%2)0..$#Fget all even indexes in@Farray, which are indexes of odd elementsmap$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"check if odd element start with-, then append-to next even element, else append a space
add a comment |
A perl one:
$ perl -anle 'BEGIN$,=" "
print map$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"grep!($_%2)0..$#F' file
-2 4 -9
3 -5 -11
-ansplit input to@FarrayBEGIN$,=" "set output field separator to a spacegrep!($_%2)0..$#Fget all even indexes in@Farray, which are indexes of odd elementsmap$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"check if odd element start with-, then append-to next even element, else append a space
A perl one:
$ perl -anle 'BEGIN$,=" "
print map$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"grep!($_%2)0..$#F' file
-2 4 -9
3 -5 -11
-ansplit input to@FarrayBEGIN$,=" "set output field separator to a spacegrep!($_%2)0..$#Fget all even indexes in@Farray, which are indexes of odd elementsmap$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"check if odd element start with-, then append-to next even element, else append a space
answered Jun 21 '15 at 15:00
cuonglmcuonglm
106k25211309
106k25211309
add a comment |
add a comment |
As @terdon's answer but without the sed:
awk ' for(i=1;i<=NF;i+=2)
if ($i<0) $(i+1)*=-1;
$i = "";
print
'
add a comment |
As @terdon's answer but without the sed:
awk ' for(i=1;i<=NF;i+=2)
if ($i<0) $(i+1)*=-1;
$i = "";
print
'
add a comment |
As @terdon's answer but without the sed:
awk ' for(i=1;i<=NF;i+=2)
if ($i<0) $(i+1)*=-1;
$i = "";
print
'
As @terdon's answer but without the sed:
awk ' for(i=1;i<=NF;i+=2)
if ($i<0) $(i+1)*=-1;
$i = "";
print
'
edited Apr 13 '17 at 12:36
Community♦
1
1
answered Jun 21 '15 at 16:03
meuhmeuh
32.5k12255
32.5k12255
add a comment |
add a comment |
A python solution
python -c 'from __future__ import print_function;
import sys, math;
for line in sys.stdin:
x = [int(y) for y in line.split()]
print(*[int(math.copysign(b, a)) for a, b in zip(x[::2], x[1::2])], sep=" ")
' <file
add a comment |
A python solution
python -c 'from __future__ import print_function;
import sys, math;
for line in sys.stdin:
x = [int(y) for y in line.split()]
print(*[int(math.copysign(b, a)) for a, b in zip(x[::2], x[1::2])], sep=" ")
' <file
add a comment |
A python solution
python -c 'from __future__ import print_function;
import sys, math;
for line in sys.stdin:
x = [int(y) for y in line.split()]
print(*[int(math.copysign(b, a)) for a, b in zip(x[::2], x[1::2])], sep=" ")
' <file
A python solution
python -c 'from __future__ import print_function;
import sys, math;
for line in sys.stdin:
x = [int(y) for y in line.split()]
print(*[int(math.copysign(b, a)) for a, b in zip(x[::2], x[1::2])], sep=" ")
' <file
answered Jun 21 '15 at 16:58
iruvariruvar
12.5k63063
12.5k63063
add a comment |
add a comment |
A simple mathematics-based awk solution:
$ cat <<M | awk 'for(i=2;i<=NF;i+=2)printf "%4s",($(i-1)<0?-1:1)*$iprint ""'
-1 2 3 4 -5 9
2 3.2 -4 5 -6
M
-2 4 -9
3.2 -5
- Loop from the second (
i=2) to the last field (i<=NF). - Multiply the previous field (
$(i-1)) with either -1 or 1. - Format the output nicely (
printf "%4s"), and print a trailing newline (print "").
The only caveat to this is that if you have an odd number of columns, the last field will not display anything at all. I hope this is what you expect. Apparently this is what you expect. :)
(edited to work with decimal values, and to make the loop conditions more aligned with the question while saving 2 characters.)
add a comment |
A simple mathematics-based awk solution:
$ cat <<M | awk 'for(i=2;i<=NF;i+=2)printf "%4s",($(i-1)<0?-1:1)*$iprint ""'
-1 2 3 4 -5 9
2 3.2 -4 5 -6
M
-2 4 -9
3.2 -5
- Loop from the second (
i=2) to the last field (i<=NF). - Multiply the previous field (
$(i-1)) with either -1 or 1. - Format the output nicely (
printf "%4s"), and print a trailing newline (print "").
The only caveat to this is that if you have an odd number of columns, the last field will not display anything at all. I hope this is what you expect. Apparently this is what you expect. :)
(edited to work with decimal values, and to make the loop conditions more aligned with the question while saving 2 characters.)
add a comment |
A simple mathematics-based awk solution:
$ cat <<M | awk 'for(i=2;i<=NF;i+=2)printf "%4s",($(i-1)<0?-1:1)*$iprint ""'
-1 2 3 4 -5 9
2 3.2 -4 5 -6
M
-2 4 -9
3.2 -5
- Loop from the second (
i=2) to the last field (i<=NF). - Multiply the previous field (
$(i-1)) with either -1 or 1. - Format the output nicely (
printf "%4s"), and print a trailing newline (print "").
The only caveat to this is that if you have an odd number of columns, the last field will not display anything at all. I hope this is what you expect. Apparently this is what you expect. :)
(edited to work with decimal values, and to make the loop conditions more aligned with the question while saving 2 characters.)
A simple mathematics-based awk solution:
$ cat <<M | awk 'for(i=2;i<=NF;i+=2)printf "%4s",($(i-1)<0?-1:1)*$iprint ""'
-1 2 3 4 -5 9
2 3.2 -4 5 -6
M
-2 4 -9
3.2 -5
- Loop from the second (
i=2) to the last field (i<=NF). - Multiply the previous field (
$(i-1)) with either -1 or 1. - Format the output nicely (
printf "%4s"), and print a trailing newline (print "").
The only caveat to this is that if you have an odd number of columns, the last field will not display anything at all. I hope this is what you expect. Apparently this is what you expect. :)
(edited to work with decimal values, and to make the loop conditions more aligned with the question while saving 2 characters.)
edited Jun 22 '15 at 15:40
answered Jun 22 '15 at 8:18
h.j.k.h.j.k.
830820
830820
add a comment |
add a comment |
You need to forget the negative entirely - leave it out. You want to consolidate two fields - from left to right. That's very easy.
sed ' s/ *(.*)/1 /
s/([0-9]* *)2/1/g
s/[ -]*$//
' <<IN
-1 2 3 4 -5 9
2 3 -4 5 -6 11
IN
-2 4 -9
3 -5 -11
Notice how I avoid any reference to the sign at all - when the input is processed the automaton will accept only spaces or numbers because it understands nothing else - all else is ignored completely and will remain in place.
When you specify a numeric repetition interval for a (subexpression), only the last occurrence of that expression is 1 back-referenced. So you can just squeeze - or truncate - a repeat interval that easily. And because we squeeze the repeat behind the sign - if there is one - the second occurrence of that pattern will follow any sign that used to precede the first.
The behavior described above is specified by POSIX for all BRE compliant applications, but very few seds get it right. GNU sed does.
Last, the spaces are just to make the pattern occurrence regular.
Of course, this will never work for you. Or, probably more correctly, it will always work for you, but never return any results. How could it if the pattern is indefinite?
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
|
show 3 more comments
You need to forget the negative entirely - leave it out. You want to consolidate two fields - from left to right. That's very easy.
sed ' s/ *(.*)/1 /
s/([0-9]* *)2/1/g
s/[ -]*$//
' <<IN
-1 2 3 4 -5 9
2 3 -4 5 -6 11
IN
-2 4 -9
3 -5 -11
Notice how I avoid any reference to the sign at all - when the input is processed the automaton will accept only spaces or numbers because it understands nothing else - all else is ignored completely and will remain in place.
When you specify a numeric repetition interval for a (subexpression), only the last occurrence of that expression is 1 back-referenced. So you can just squeeze - or truncate - a repeat interval that easily. And because we squeeze the repeat behind the sign - if there is one - the second occurrence of that pattern will follow any sign that used to precede the first.
The behavior described above is specified by POSIX for all BRE compliant applications, but very few seds get it right. GNU sed does.
Last, the spaces are just to make the pattern occurrence regular.
Of course, this will never work for you. Or, probably more correctly, it will always work for you, but never return any results. How could it if the pattern is indefinite?
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
|
show 3 more comments
You need to forget the negative entirely - leave it out. You want to consolidate two fields - from left to right. That's very easy.
sed ' s/ *(.*)/1 /
s/([0-9]* *)2/1/g
s/[ -]*$//
' <<IN
-1 2 3 4 -5 9
2 3 -4 5 -6 11
IN
-2 4 -9
3 -5 -11
Notice how I avoid any reference to the sign at all - when the input is processed the automaton will accept only spaces or numbers because it understands nothing else - all else is ignored completely and will remain in place.
When you specify a numeric repetition interval for a (subexpression), only the last occurrence of that expression is 1 back-referenced. So you can just squeeze - or truncate - a repeat interval that easily. And because we squeeze the repeat behind the sign - if there is one - the second occurrence of that pattern will follow any sign that used to precede the first.
The behavior described above is specified by POSIX for all BRE compliant applications, but very few seds get it right. GNU sed does.
Last, the spaces are just to make the pattern occurrence regular.
Of course, this will never work for you. Or, probably more correctly, it will always work for you, but never return any results. How could it if the pattern is indefinite?
You need to forget the negative entirely - leave it out. You want to consolidate two fields - from left to right. That's very easy.
sed ' s/ *(.*)/1 /
s/([0-9]* *)2/1/g
s/[ -]*$//
' <<IN
-1 2 3 4 -5 9
2 3 -4 5 -6 11
IN
-2 4 -9
3 -5 -11
Notice how I avoid any reference to the sign at all - when the input is processed the automaton will accept only spaces or numbers because it understands nothing else - all else is ignored completely and will remain in place.
When you specify a numeric repetition interval for a (subexpression), only the last occurrence of that expression is 1 back-referenced. So you can just squeeze - or truncate - a repeat interval that easily. And because we squeeze the repeat behind the sign - if there is one - the second occurrence of that pattern will follow any sign that used to precede the first.
The behavior described above is specified by POSIX for all BRE compliant applications, but very few seds get it right. GNU sed does.
Last, the spaces are just to make the pattern occurrence regular.
Of course, this will never work for you. Or, probably more correctly, it will always work for you, but never return any results. How could it if the pattern is indefinite?
edited Jun 22 '15 at 12:26
answered Jun 21 '15 at 22:46
mikeservmikeserv
46.1k669164
46.1k669164
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
|
show 3 more comments
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
This will only work if there is an even number of fields.
– terdon♦
Jun 22 '15 at 12:26
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
@terdon - nope - it works for whatever.
– mikeserv
Jun 22 '15 at 12:27
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
No, try it with an odd number of fields. The last one is printed and it shouldn't be.
– terdon♦
Jun 22 '15 at 12:31
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
@terdon - why shouldn't it be? There is no following field to cancel it out? The asker states they want to remove odd columns followed by an even column. The last column is not followed by an even column - it does exactly what it should, and removes as little as possible. Assuming some data should go is bad practice in my opinion.
– mikeserv
Jun 22 '15 at 12:32
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
No they don't: "So I need the values from the even columns unchanged and of the odd columns, if there's a negative value, keep the - only and if there's a positive value, discard it." Odd fields should never be printed, the only information they should impart is whether they were negative. Yours prints positive odd fields.
– terdon♦
Jun 22 '15 at 12:33
|
show 3 more comments
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- 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%2funix.stackexchange.com%2fquestions%2f211138%2fremoving-numeric-values-in-certain-columns-whilst-keeping-minus-signs%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
When you say your dataframe continues indefinitely, do you mean horizontally or vertically? How many columns do you actually have?
– terdon♦
Jun 21 '15 at 14:36
Both. My test data is 3 rows by 3 columns but the actual data has varying numbers, I'd say up 40 rows and 40 columns.
– Asfound
Jun 21 '15 at 14:41