0

I have a long list of strings like this:

_ah_
_asn_
_ai_
_errr_
_an_

And I would like to transform it like to this

"_ah_ai_an_",
"_asn_",
"_errr_"

I have tried :

cat file | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2-

Which essentially sort it by length but what I am trying to do is to have those of the same length on the same line with "," As delimiters

1
  • How long is that list? Notice that all the answers work by storing the whole file in the memory, which you do NOT want to do with a >> multi GB file. Besides, the challenge would've been much fun if that was a requirement ;-) – mosvy Mar 20 '20 at 12:36
2

This gives the output you want:

awk -F_ '
    {strr[length] = strr[length]"_"$2}
    length > max {max=length}
    END {
        for (i=1;i<max;i++) {if (strr[i]) print "\"" strr[i]"_\","}
        print "\"" strr[max]"_\""
    }' file

Lines with length i are appended to strr[i] with a leading _. At the end, we just loop through existing strr elements and output them with "<element>_",, except for the last element, which gets no ,.

4
  • 1
    @EdMorton Of course, you know that you should have written: `awk 'BEGIN{print "\0427\042"}' for the last example. – Isaac Mar 20 '20 at 4:31
  • This will print a bogus "_" line for an empty file. And if you really hate repeating "\"", you can set a variable: awk -v q='"' .... – mosvy Mar 20 '20 at 12:54
  • 1
    @EdMorton Thank you for your suggestion, I updated the answer. It was pointed out to me in the past that the octal quotes was a better idea for the case the awk body would be converted to a script on its own, but of course that is only for ' and not for ". – Quasímodo Mar 20 '20 at 16:33
  • Right, that's only for ' (see awk.freeshell.org/PrintASingleQuote) and you should always use \047 for that, not just \47. – Ed Morton Mar 20 '20 at 17:11
6
$ cat tst.awk
{
    lgth = length($0)
    sub(/_$/,"",strs[lgth])
    strs[lgth] = strs[lgth] $0
}
END {
    for (lgth in strs) {
        printf "%s\"%s\"", sep, strs[lgth]
        sep = "," ORS
    }
    print ""
}

$ awk -f tst.awk file
"_ah_ai_an_",
"_asn_",
"_errr_"

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.