0

Using the input file, I will like to generate the desired output.

I am trying to figure out how to get exactly the desired output results, using the code shown below.

The information in the column 2 for input file needs to be in output file from column 21 to 80, filling all this range.

Output desired:

X52152              1214-1216,1218-1221,1233,1222,1245,1223,1246,1249,1251,     
X52152              1224-1232,1234-1243,1247,1250,1253-1254,1332,1331,1333-1336,
X52152              1338,1337,1339-1340,1467.                                   
X52155              1215-1216,1218-1221,1233,1222,1245,1223,1246,1249,1251,1248,
X52155              1224-1232,1234-1243,1247,1250,1253-1254,1332,1331,1333-1336,
X52155              1338,1337,1339-1341.                                         

Here the code used.

awk '                                                            
  function range_to_out() {                                      
    out=(out sep (start == last ? start : (start "-" last)))     
  }                                                              
  function print_out() {                                         
    printf "%s              %s\n", p1, out","                                   
  }                                                              
  NR == 1 { start=last=$2; p1=$1; next }                         
  {                                                              
    if ($2 == last+1) { last=$2 } else {                         
      range_to_out(); sep=","; start=last=$2                     
    }                                                            
  }                                                              
  $1 != p1 || length(out) > 50 { print_out(); sep=out=""; p1=$1 }
  END { range_to_out(); print_out() }                            
' file

this question is similar to one done previously, were i got an code from Mr.glenn jackman. Here his code. this code works perfectly with other input file using single column.

  awk '                                                                    
    function printrange() { print start (start == last ? "" : "-" last) }
    NR == 1 {start=last=$1; next}                                        
    $1 == last+1 {last=$1; next}                                         
    {printrange(); start=last=$1}                                        
    END {printrange()}                                                   
' file | paste -sd" " | fold -sw 60 | tr ' ' ',' | sed 's/^/111111              /'

Thanks in advance.

Input file

X52152      1214
X52152      1215
X52152      1216
X52152      1218
X52152      1219
X52152      1220
X52152      1221
X52152      1233
X52152      1222
X52152      1245
X52152      1223
X52152      1246
X52152      1249
X52152      1251
X52152      1224
X52152      1225
X52152      1226
X52152      1227
X52152      1228
X52152      1229
X52152      1230
X52152      1231
X52152      1232
X52152      1234
X52152      1235
X52152      1236
X52152      1237
X52152      1238
X52152      1239
X52152      1240
X52152      1241
X52152      1242
X52152      1243
X52152      1247
X52152      1250
X52152      1253
X52152      1254
X52152      1332
X52152      1331
X52152      1333
X52152      1334
X52152      1335
X52152      1336
X52152      1338
X52152      1337
X52152      1339
X52152      1340
X52152      1467
X52155      1215
X52155      1216
X52155      1218
X52155      1219
X52155      1220
X52155      1221
X52155      1233
X52155      1222
X52155      1245
X52155      1223
X52155      1246
X52155      1249
X52155      1251
X52155      1248
X52155      1224
X52155      1225
X52155      1226
X52155      1227
X52155      1228
X52155      1229
X52155      1230
X52155      1231
X52155      1232
X52155      1234
X52155      1235
X52155      1236
X52155      1237
X52155      1238
X52155      1239
X52155      1240
X52155      1241
X52155      1242
X52155      1243
X52155      1247
X52155      1250
X52155      1253
X52155      1254
X52155      1332
X52155      1331
X52155      1333
X52155      1334
X52155      1335
X52155      1336
X52155      1338
X52155      1337
X52155      1339
X52155      1340
X52155      1341
OXXO
  • 724
  • 5
  • 12
  • [edit] your question to include concise, testable sample input and expected output. Don't expect us to go visiting external sites for either. If it's too big to fit in your question then you need to create a more minimal example. We do **not** expect to see a sample with 80+ columns! See [ask] and in particular not the part about creating a [mcve]. – Ed Morton May 20 '18 at 14:48
  • Ed, I have added the input file, it as bit long but needed for the purpose. tks – OXXO May 20 '18 at 15:03
  • Why does it need to be so long? It seems to me like the input could be about one-tenth of that length and you could specify the desired output to be a quarter the width and still express the same problem without us having to wade through so much input data to try to understand it. – Ed Morton May 20 '18 at 15:08
  • Ed, I understand, is it better I edit the input file? Or keep it like this and take your advice for future questions. Tks – OXXO May 20 '18 at 16:30
  • Applying Ed Morton's excellent advice is a great way to improve this question and the more you improve it, the more chance people will want to help. – jas May 20 '18 at 17:07
  • I have remove some data, to short the input fille – OXXO May 20 '18 at 17:25
  • Please can somebody help with this, tks – OXXO May 21 '18 at 20:53
  • Possible duplicate of [Why does my tool output overwrite itself and how do I fix it?](https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it) – kvantour May 24 '18 at 13:31
  • 1
    The reason why it is not working is due to the carriage return in your input. You have to get rid of that DOS `\r`. Hence the duplicate mark. – kvantour May 24 '18 at 13:32

1 Answers1

2

Your awk code would look like :

function print_stuff(label,string,    t) {
    # abuse $0 as it makes life easy
    t = $0; $0 = string;
    # replace values with "-" if a-1,a,a+1
    for (i=2;i<NF;++i) {
        if      ($i == $(i-1)+1 && $i == $(i+1)-1) $i="-"
        else if ($(i-1) == "-"  && $i == $(i+1)-1) $i="-"
        else if ($i == $(i-1)+1)                   $i="- "$i
    }
    # substitute all " - - - " with "-" and all  " " with ","
    gsub(/ [ -]+/,"-"); gsub(/ /,",")
    # print columns
    while (length($0)>=60) {
       match(substr($0,1,60),/,[^,]*$/)
       printf "%-20s", label; print substr($0,1,RSTART)
       $0=substr($0,RSTART+1)
    }
    printf "%-20s", label; print $0"."
    $0 = t;
}
{ gsub(/\r/,"",$0) }             # get rid of the cariage return
(NR == 1) { a=$1; b = $2; next } # initialize
(a == $1) { b = b" "$2; next }   # append values
(a != $1) {  print_stuff(a,b); a = $1; b = $2 } # print
END { print_stuff(a,b) }         # print last

This outputs :

$ awk -f main.awk <file>

X52152              1214-1216,1218-1221,1233,1222,1245,1223,1246,1249,1251,
X52152              1224-1232,1234-1243,1247,1250,1253-1254,1332,1331,1333-1336,
X52152              1338,1337,1339-1340,1467.
X52155              1215-1216,1218-1221,1233,1222,1245,1223,1246,1249,1251,1248,
X52155              1224-1232,1234-1243,1247,1250,1253-1254,1332,1331,1333-1336,
X52155              1338,1337,1339-1341.
kvantour
  • 25,269
  • 4
  • 47
  • 72
  • Hi Kvantour, amazing code and perfect explanation. I see something strange your code output 1250,1253,1254,1332 and should be 1250,1253-1254,1332 as 1253 and 1254 are continuous numbers. Kindly can you fix it in your code, then it will perfect. many tks. also 1339,1340 should be 1339-1340. – OXXO May 24 '18 at 14:25
  • @OXXO I have updated the code. Please be advised that the original question was very unclear as the specifications were missing. Also, bear in mind that we are not a coding service. We like to help people out, but you cannot expect us to provide an off the shelf solution for you. – kvantour May 24 '18 at 15:30
  • Kvantour,Tks, I am learning and getting knowledges from the experts in the forum, i try always to code myself before posting a question. And for improvement i asked some questions.Appreciate your comments and for sure I will keeping improving. I have posted some codes with the objetive to perfection the code with the expertise of users in the forum.. Again thank you. – OXXO May 24 '18 at 17:04
  • Kvantour, kindly can you recommend a AWK online training tks. – OXXO May 27 '18 at 05:02
  • @OXXO I would start going through [Awk one-liners explained](http://www.catonmat.net/blog/awk-one-liners-explained-part-one/). This gives you a lot of information about how awk works. Afterward, open the manual or standard and read about various existing functions. – kvantour May 30 '18 at 09:26
  • Kvantour, Appreciate your advise, tks – OXXO May 30 '18 at 11:23