Unix one-liner to swap/transpose two lines in multiple text files?

后端 未结 8 1886
谎友^
谎友^ 2021-01-06 03:22

I wish to swap or transpose pairs of lines according to their line-numbers (e.g., switching the positions of lines 10 and 15) in multiple text files using a UNIX tool such a

8条回答
  •  灰色年华
    2021-01-06 04:21

    If you want to swap two lines, you can send it through twice, you could make it loop in one sed script if you really wanted, but this works:

    e.g.

    test.txt: for a in {1..10}; do echo "this is line $a"; done >> test.txt

    this is line 1
    this is line 2
    this is line 3
    this is line 4
    this is line 5
    this is line 6
    this is line 7
    this is line 8
    this is line 9
    this is line 10
    

    Then to swap lines 6 and 9:

    sed ':a;6,8{6h;6!H;d;ba};9{p;x};' test.txt | sed '7{h;d};9{p;x}'

    this is line 1
    this is line 2
    this is line 3
    this is line 4
    this is line 5
    this is line 9
    this is line 7
    this is line 8
    this is line 6
    this is line 10
    

    In the first sed it builds up the hold space with lines 6 through 8. At line 9 it prints line 9 then prints the hold space (lines 6 through 8) this accomplishes the first move of 9 to place 6. Note: 6h; 6!H avoids a new line at the top of the pattern space.

    The second move occurs in the second sed script it saves line 7 to the hold space, then deletes it and prints it after line 9.

    To make it quasi-generic you can use variables like this: A=3 && B=7 && sed ':a;'${A}','$((${B}-1))'{'${A}'h;'${A}'!H;d;ba};'${B}'{p;x};' test.txt | sed $(($A+1))'{h;d};'${B}'{p;x}'

    Where A and B are the lines you want to swap, in this case lines 3 and 7.

提交回复
热议问题