LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   operation of "tac" in sed (https://www.linuxquestions.org/questions/programming-9/operation-of-tac-in-sed-664806/)

dina3e 08-23-2008 08:51 AM

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 .

ta0kira 08-24-2008 11:54 AM

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'
ls -ld ~ | sed '1!G;h'
ls -l ~ | sed 'G;h'
ls -l ~ | sed '1!G;h'
ls -l ~ | sed '1!G;h;$!d'

I'm not sure how that extra blank line ends up in the hold space. I'm probably missing something.
ta0kira

Kenhelm 08-24-2008 01:36 PM

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
Lines processed          0        1        2        3
Contents of line1        A        Line1 has been deleted
Contents of line2        B        B        Line2 has been deleted
Contents of line3        C        C        C        C\nB\nA

Contents of hold space    Empty    A        B\nA      C\nB\nA


Mr. C. 08-24-2008 05:34 PM

Sometimes its simplifies understanding by translate sed code into more natural pseudocode:
Code:

sed '1!G;h;$!d'

#1
if not line 1 then
  append newline + hold space to end of pattern space
endif

#2
move pattern space to hold space

#3
if not last line then
  delete pattern space
endif

Keep in mind the line number of the pattern space doesn't have to change with each change to pattern or hold space. Rather, line numbers are considered as *input* lines, not pattern space lines numbers.

ta0kira 08-24-2008 06:08 PM

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

Mr. C. 08-24-2008 06:40 PM

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

Kenhelm 08-24-2008 07:28 PM

Another diagram:
Again using a file of 3 lines A, B, C
Code:

                      Pattern space              Hold space
1st cycle:
after line1 input          A                        Empty
after 1!G                  A                        Empty
after h                    A                        A
after $!d                  Empty                    A

2nd cycle:
after line2 input          B                        A
after 1!G                  B\nA                      A
after h                    B\nA                      B\nA
after $!d                  Empty                    B\nA

3rd cycle:
after line3 input          C                        B\nA
after 1!G                  C\nB\nA                  B\nA
after h                    C\nB\nA                  C\nB\nA
after $!d                  C\nB\nA                  C\nB\nA


ta0kira 08-24-2008 08:45 PM

Thanks. Very helpful.
ta0kira


All times are GMT -5. The time now is 03:31 PM.