Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
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.
I need to sort lines inside blocks in a file, not between blocks, and not sort blocks.
"Block": two new-line characters together
sample file:
xyz
def
opq
ghi
abc
rstuu
442
fde
932
desired output:
def
opq
xyz
442
abc
ghi
rstuu
932
fde
Which language or command would you use ? (sort, msort, sed, awk, perl, pyhton, bash-script, etc)
Which is the better for this ?
Could anybody help me to write a script to do this ?
But your solution only works if each line not contain any space character. In this case, your solution deletes the line.
I've posted this file only as sample file. The lines can contain any character (can begin with space for example, can contain a space in any position, etc)
This is the rule:
line: between only one new line character
block: between two or more new line characters (collection of lines)
I hope you can help me.
Thanks in advance.
Leandro.
Quote:
Originally Posted by suhas!
Hey.... I dont know the better way to do it.. but here is my ugly solution....
Here is an awk code, which stores in the indexes of an array the lines in a block. Every time it encounters an empty line, the indexes of the array are sorted and printed out. The END statement ensures the last block is printed even if there is no empty line at the end of the file:
Code:
!/^$/{
array[$0] = 1
}
/^$/ { n = asorti(array,sorted)
for ( i = 1; i <= n; i++ ) {
print sorted[i]
delete array[sorted[i]]
delete sorted[i]
}
print ""
}
END { n = asorti(array,sorted)
for ( i = 1; i <= n; i++ ) {
print sorted[i]
delete array[sorted[i]]
delete sorted[i]
}
}
Just take in mind that indexes of the arrays in awk can be any string, so that I store the content of the line as index of the array, not as value of an array's element. Hope this helps!
Another clue: if in the same block there are duplicated lines, the code above prints out just one of them. To be sure all of them are printed out, just count their occurrences:
Code:
!/^$/{
array[$0] += 1
}
/^$/ { n = asorti(array,sorted)
for ( i = 1; i <= n; i++ ) {
for (j = 1; j <= array[sorted[i]]; j++)
print sorted[i]
delete array[sorted[i]]
delete sorted[i]
}
print ""
}
END { n = asorti(array,sorted)
for ( i = 1; i <= n; i++ )
for (j = 1; j <= array[sorted[i]]; j++)
print sorted[i]
}
I have just only one question now.
Does this script still work if there is no empty line at the beginning of the file ?
How I have to execute your script ?
awk -F your_script file_to_process
Regards.
Leandro.
Quote:
Originally Posted by colucix
Here is an awk code, which stores in the indexes of an array the lines in a block. Every time it encounters an empty line, the indexes of the array are sorted and printed out. The END statement ensures the last block is printed even if there is no empty line at the end of the file:
Code:
!/^$/{
array[$0] = 1
}
/^$/ { n = asorti(array,sorted)
for ( i = 1; i <= n; i++ ) {
print sorted[i]
delete array[sorted[i]]
delete sorted[i]
}
print ""
}
END { n = asorti(array,sorted)
for ( i = 1; i <= n; i++ ) {
print sorted[i]
delete array[sorted[i]]
delete sorted[i]
}
}
Just take in mind that indexes of the arrays in awk can be any string, so that I store the content of the line as index of the array, not as value of an array's element. Hope this helps!
Does this script still work if there is no empty line at the beginning of the file ?
Yes. If there is an empty line at the beginning, it just print out the empty line, keeping the same structure in the output (all the empty lines are printed out as is).
Quote:
Originally Posted by llattan
How I have to execute your script ?
awk -F your_script file_to_process
Nope. You have to use the -f (lowercase) option. The -F (uppercase) has another meaning: it specifies the field separator, FS being used by 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.