ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
It is desired to sort all of the blank-delimited words within each line, without regard to the words in other lines. To illustrate by example, this input file ...
Quote:
Once upon a midnight dreary, while I pondered weak and weary,
Over many a quaint and curious volume of forgotten lore,
While I nodded, nearly napping, suddenly there came a tapping,
As of some one gently rapping, rapping at my chamber door.
''Tis some visitor,' I muttered, 'tapping at my chamber door -
Only this, and nothing more.
... would be changed to this output file ...
Quote:
a and dreary I midnight Once pondered upon weak weary while
a and curious forgotten lore many of Over quaint volume
a came I napping nearly nodded suddenly tapping there While
As at chamber door gently my of one rapping rapping some
and more nothing Only this
This is a solved problem! However, I am starting to learn awk and wonder if awk has a simpler way to perform this transformation.
Every awk program has three parts: a BEGIN block, which is executed once before any input is read; a main loop, which is executed for every line of input; and an END block, which is executed after all of the input is read.
This might be interpreted (or misinterpreted) to mean that a sort command in the main loop will sort the words in every line of input. Too good to be true? This code ...
$ awk -v IGNORECASE=1 '{gsub(/[[:punct:]]/, ""); split($0, w); s=""; for(i=1; i<=asort(w); i++) s=s w[i] " "; print s }' infile.txt
a and dreary I midnight Once pondered upon weak weary while
a and curious forgotten lore many of Over quaint volume
a came I napping nearly nodded suddenly tapping there While
As at chamber door gently my of one rapping rapping some
at chamber door I muttered my some tapping Tis visitor
and more nothing Only this
Firstfire, asort() is specific to GNU awk, so better use gawk (and not awk) since it won't work with generic awks. Plus you add trailing spaces.
Here's my version, long but well commented.
Code:
awk '{
n = split("", list) # n = 0, list = empty array
# For loop over all fields in this record
for (f = 1; f <= NF; f++) {
# i = the position to insert in the list
i = 1
# Skip earlier ones
while (i <= n && list[i] < $f) i++
# Move later ones
for (o = n; o >= i; o--)
list[o+1] = list[o]
# Insert this field
list[i] = $f
# List grew by one
n++
}
# output list, using spaces as separators.
for (i = 1; i < n; i++)
printf("%s ", list[i])
printf("%s\n", list[n])
}'
Thanks for both responses. I've timed both and find the execution times nearly equal, and much faster than the solution I coded before posting this thread.
Thank you, firstfire, for introducing me to asort. I stand in awe of a one-line solution to a non-trivial text-processing question.
Thank you, Nominal Animal, for the well-commented and instructive code.
It will take some time for me to digest the logic of these solutions. I'm travelling a path of self-education in Linux. At the outset I decided to develop a competence with use of grep, sed, cut, paste, sort, uniq before moving on to awk. I now see that as a short-sighted approach and will henceforth delve deeper into awk.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.