3

I have data of the following format:

2342 1
6473 2
7463 2
3647
2734 1
9343

The lines that do not have a value in the 2nd column are empty in that spot (i.e. there is no space, tab etc.). I am looking for a simple command that puts a '-9' in the open places of column 2.

(Basically an awk command that checks if the line is non-zero in column 2, and then add '-9' if that's the case should do it I'd say..)

Extended example (data with more columns, some of which containing missings). I only want to add '-9' to the last column (i.e. the other columns are allowed to have missings).

2342 0 12 1
6473   13 2
7463 0 14 2
3647 0  
2734 0    1
9343 0 16 
  • Something like: awk '{if (foo[$2]!=1) || (foo[$2]!=2); then {print "-9"}}' foo, which clearly doesn't work. – mats Aug 13 '15 at 11:57
  • It seems like you are trying to run kill -9 pid which is wrong. Use kill -l to see all available signals en what you need to use instead. – Valentin Bajrami Aug 13 '15 at 12:01
  • How are your fields separated? Are they always at fixed offsets within the line (0, 5, 7, 10)? – Stéphane Chazelas Aug 13 '15 at 12:29
  • @Stéphane Chazelas, Space delimited. However, if the last column doesn't contain a value it also doesn't have a space (i.e. those lines end after the last real value). I hope it's clear what I'm trying to say here. – mats Aug 13 '15 at 12:32
  • Does your 5th line in your second example have fields 1, 2, 3 (fields separated by any amount of space), 1, 2, 4 (fixed width fields), or 1, 2, 6 (fields separated by one space, and there are 4 spaces between 0 and 1) (same goes for the 2nd line). – Stéphane Chazelas Aug 13 '15 at 12:42
4

If your data is expressed in fixed width columns, you could do:

For the first case:

sed 's/^.\{4\}$/& -9/'

(add " -9" to lines of 4 characters).

For the second case:

sed -e '/.\{11\}/b' -e 's/$/          /;s/\(.\{10\}\).*/\1-9/'

(add up to 10 spaces and -9 to lines of less than 11 characters).

Generally, to parse lines with fixed width fields, see the FIELDWIDTHS special variable of GNU awk.

  • add up to 10 spaces Doesn't it add 10 spaces everytime? – 123 Aug 13 '15 at 13:17
  • @User112638726, no, it adds 10 spaces (first s command), then only retains the first 10 characters. So for empty lines, it adds 10 spaces, and for lines with 9 characters, it adds one. – Stéphane Chazelas Aug 13 '15 at 13:20
  • Oh right, i thought you were documenting what the sed was doing, not the end result. – 123 Aug 13 '15 at 13:24
1

With GNU sed

sed ':;s/^.\{0,9\}$/& /;t;s/^.\{10\}$/&-9/' file

Adds one space as long a the number of characters is below ten using test t.
Then replaces lines with ten character with themselves and -9.

  • Defining an empty label works by accident in GNU sed, I would advise against doing it. t or b without a label are meant to jump to the end (start the next cycle), and is documented as such even in GNU sed. POSIXly: sed -e :1 -e 's/^.\{0,9\}$/& /;t1' -e 's/^.\{10\}$/&-9/' – Stéphane Chazelas Aug 13 '15 at 13:34
  • @StéphaneChazelas Yep, i remembered you telling me last time which is why i specified GNU. I thought it was supposed to work that way though in GNU. – 123 Aug 13 '15 at 14:14
  • It's not supposed to work that way, it just works by accident, GNU sed doesn't check for an empty label on ":" and upon t/b looks in the list of defined labels first before considering an empty label as the special case it's meant to be. It is not documented to work that way. It may not work that way in future versions. – Stéphane Chazelas Aug 13 '15 at 14:23
  • @StéphaneChazelas Thanks,I'll keep that in mind. – 123 Aug 13 '15 at 14:33
  • 1
    Dammit @StéphaneChazelas, you've no idea how many of my code-golf answers you've screwed up with this ;-) – Digital Trauma Feb 3 '16 at 16:21
0

You can try with this awk with your first example:

awk 'NF == 1 { $2 = -9; } 1' file

As mentioned in other posts with gawk you can use FIELDWIDTHS, so you can try this with your second one:

gawk 'BEGIN { FIELDWIDTHS = "4 1 1 1 2 1 1"} { for (i = 1; i <= NF; i++) { if ($i == "") { if (i == 7) $i = "-9"; else $i = " "; } } printf("%s %s %s %s\n", $1, $3, $5, $7); }' file
  • Thanks @taliezin, for the example this works fine. However, I think it won't work properly if my file has multiple columns that may contain missings as well.. – mats Aug 13 '15 at 12:07
  • This is for your given example, can you add different example and I'll delete answer as inappropriate? And with more columns you can not determine which column is missing. – taliezin Aug 13 '15 at 12:09
  • I added an extended data example. Unfortunately your solution doesn't work anymore in this case. – mats Aug 13 '15 at 12:31
0

You can use this:

perl -ane 'if(!$F[1]){print $F[0]," -9\n"}else{print $_;}'

This command reads your input line-wise and prints a "-9" in the second column, if it is empty.

echo "2342 1
6473 2
7463 2
3647
2734 1
9343" | perl -ane 'if(!$F[1]){print $F[0]," -9\n"}else{print $_;}'

2342 1
6473 2
7463 2
3647 -9
2734 1
9343 -9

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.