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 ;-)
    – user313992
    Mar 20, 2020 at 12:36

2 Answers 2

5
$ 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_"
1

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.
    – user232326
    Mar 20, 2020 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='"' ....
    – user313992
    Mar 20, 2020 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, 2020 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, 2020 at 17:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .