operation of "tac" in sed
i had gone through "sed" i found that the "tac" implemntion in sed. it really work fine.
sed '1!G;h;$!d' file_name but my question is how the internally the 'sed' works for this line of code how the h(hold) and G(get) works in the hold space to pattern space in the execution of the hole file . |
I have an idea of how it works, but I'm having trouble making it into something logical. Try the following and look at the differences in their outputs:
Code:
ls -ld ~ | sed 'G;h' ta0kira |
sed '1!G;h;$!d' does this to each line in turn:-
If it's not line1, append '\nHold space contents' to it (\n = newline); Then copy it to the hold space (deletes previous contents); Then, if it's not the last line, delete it. The whole file ends up on the last line, other lines having been deleted. e.g. A file with 3 lines A, B, C Code:
State after each line has been processed by sed |
Sometimes its simplifies understanding by translate sed code into more natural pseudocode:
Code:
sed '1!G;h;$!d' |
I think it's pretty obvious what the commands mean, but I don't think anyone's explained how that results in reversing of the lines. I've gotten as far as the pseudo-code in my head, but it doesn't seem to translate into the end result. I've been executing it one line at a time in my head and honestly can't explain the state of each buffer at every step of the way, which is what I think OP is asking.
ta0kira |
Kenhelm's diagram shows the state of each line. I've edited my post above to label Steps as #1, #2, and #3. From these descriptions, it is pretty trivial to construct the flow:
For file containing: A B C First, for line 1. Pattern space for line 1 is A. Step #1 is skipped, because we're on line 1. Step #2 moves pattern space (A) to hold space which is empty. Hold space is now A. Step #3 deletes pattern space, so Pattern space for line 1 is now empty. Result: Hold space = "A", Pattern space = "". Now, for line 2. Pattern space is "B" (because line 2 was just read). Step #1 appends newline + hold space to pattern space, thus "\n" + "A" goes to end of current pattern space of "B". Leaves pattern space as "B\nA". Step #2 moves pattern space of "B\n\A" to hold space. Step #3 deletes pattern space. Result: Hold space = "B\nA", Pattern space = "". Finally, for line 3. Pattern space is "C" (again, this was just read). Step #1 appends newline + hold space to pattern space, thus "\n" + "B\nA" goes to end of current pattern space of "C". Leaves pattern space as "C\nB\nA". Step #2 copies pattern space to hold space. Hold space now "C\nB\nA". Step #3 is skipped, because we're at last line. Result: Hold space = "C\nB\nA", Pattern space = "C\nB\nA". Sed's default action is to print pattern space, which is "C\nB\nA", the reverse of the input. So output is: C B A QED |
Another diagram:
Again using a file of 3 lines A, B, C Code:
Pattern space Hold space |
Thanks. Very helpful.
ta0kira |
All times are GMT -5. The time now is 03:31 PM. |