Perform sed operations on given line numbers

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
1












I am wondering whether there is a simple way to operate on certain lines with preassigned line numbers.



Let's say I want to output the 1st, 7th, 14th and 16th lines of a file, I can simply do



sed -n '1p;7p;14p;16p' input_file


but this gets more complicated when the operation is not just printing, and I don't want to write the same long command 4 times (and yes, I know I can construct this long sed command by substituting the same bash variable 4 times, but that's not ideal enough ...) , i.e.



sed -n '1long_command;7long_command;14long_command;16long_command' input_file


Is there a way to do the operation on these specific lines of my file? I am expecting something like,



sed -n '1,7,14,16p'


which certainly will not work in the current form.



Any help will be appreciated. "No, it is not possible." with explanations is also an answer that I will accept.







share|improve this question






















  • it's easy with awk
    – RomanPerekhrest
    Jan 15 at 16:40














up vote
7
down vote

favorite
1












I am wondering whether there is a simple way to operate on certain lines with preassigned line numbers.



Let's say I want to output the 1st, 7th, 14th and 16th lines of a file, I can simply do



sed -n '1p;7p;14p;16p' input_file


but this gets more complicated when the operation is not just printing, and I don't want to write the same long command 4 times (and yes, I know I can construct this long sed command by substituting the same bash variable 4 times, but that's not ideal enough ...) , i.e.



sed -n '1long_command;7long_command;14long_command;16long_command' input_file


Is there a way to do the operation on these specific lines of my file? I am expecting something like,



sed -n '1,7,14,16p'


which certainly will not work in the current form.



Any help will be appreciated. "No, it is not possible." with explanations is also an answer that I will accept.







share|improve this question






















  • it's easy with awk
    – RomanPerekhrest
    Jan 15 at 16:40












up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





I am wondering whether there is a simple way to operate on certain lines with preassigned line numbers.



Let's say I want to output the 1st, 7th, 14th and 16th lines of a file, I can simply do



sed -n '1p;7p;14p;16p' input_file


but this gets more complicated when the operation is not just printing, and I don't want to write the same long command 4 times (and yes, I know I can construct this long sed command by substituting the same bash variable 4 times, but that's not ideal enough ...) , i.e.



sed -n '1long_command;7long_command;14long_command;16long_command' input_file


Is there a way to do the operation on these specific lines of my file? I am expecting something like,



sed -n '1,7,14,16p'


which certainly will not work in the current form.



Any help will be appreciated. "No, it is not possible." with explanations is also an answer that I will accept.







share|improve this question














I am wondering whether there is a simple way to operate on certain lines with preassigned line numbers.



Let's say I want to output the 1st, 7th, 14th and 16th lines of a file, I can simply do



sed -n '1p;7p;14p;16p' input_file


but this gets more complicated when the operation is not just printing, and I don't want to write the same long command 4 times (and yes, I know I can construct this long sed command by substituting the same bash variable 4 times, but that's not ideal enough ...) , i.e.



sed -n '1long_command;7long_command;14long_command;16long_command' input_file


Is there a way to do the operation on these specific lines of my file? I am expecting something like,



sed -n '1,7,14,16p'


which certainly will not work in the current form.



Any help will be appreciated. "No, it is not possible." with explanations is also an answer that I will accept.









share|improve this question













share|improve this question




share|improve this question








edited Jan 15 at 17:21

























asked Jan 15 at 16:37









Weijun Zhou

1,434119




1,434119











  • it's easy with awk
    – RomanPerekhrest
    Jan 15 at 16:40
















  • it's easy with awk
    – RomanPerekhrest
    Jan 15 at 16:40















it's easy with awk
– RomanPerekhrest
Jan 15 at 16:40




it's easy with awk
– RomanPerekhrest
Jan 15 at 16:40










3 Answers
3






active

oldest

votes

















up vote
11
down vote



accepted










You can use branches:



sed '
1b1
7b1
14b1
16b1

# for the rest to be left alone, branch off (or delete them with "d"):
b

:1
long_command'


(note that you can also add some 20,25b1 line ranges, or /re/b1 to include lines that match the re).



Or you could use awk:



awk 'NR == 1 || NR == 7 || ... stuff'


Or using a hash:



awk -v l=1,7,14,16 '
BEGINsplit(l, a, ","); for (i in a) lines[a[i]]

NR in lines stuff'


(or BEGINlines[1]lines[7]lines[14]lines[16] if there aren't too many)






share|improve this answer






















  • Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
    – Weijun Zhou
    Jan 15 at 16:44










  • how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
    – qodeninja
    Jul 28 at 20:47

















up vote
3
down vote













Simply invert your selection and delete it:



sed '2,6d;8,13d;15d;17,$d;long_command'





share|improve this answer




















  • This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
    – Weijun Zhou
    Jan 15 at 17:08

















up vote
1
down vote













First variant:



You can use this trick:



sed -nf <(printf '%dpn' 1 7 14 16)



-f script-file - add the contents of script-file to the commands to be executed.




Testing



seq 1 20 | sed -nf <(printf '%dpn' 1 7 14 16)


Output



1
7
14
16


Second variant:



In the beginning, the auxiliary sed is used for filtering only needed lines from the file, then these lines piped to the main sed with the long command.



sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'





share|improve this answer






















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f417284%2fperform-sed-operations-on-given-line-numbers%23new-answer', 'question_page');

    );

    Post as a guest






























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    11
    down vote



    accepted










    You can use branches:



    sed '
    1b1
    7b1
    14b1
    16b1

    # for the rest to be left alone, branch off (or delete them with "d"):
    b

    :1
    long_command'


    (note that you can also add some 20,25b1 line ranges, or /re/b1 to include lines that match the re).



    Or you could use awk:



    awk 'NR == 1 || NR == 7 || ... stuff'


    Or using a hash:



    awk -v l=1,7,14,16 '
    BEGINsplit(l, a, ","); for (i in a) lines[a[i]]

    NR in lines stuff'


    (or BEGINlines[1]lines[7]lines[14]lines[16] if there aren't too many)






    share|improve this answer






















    • Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
      – Weijun Zhou
      Jan 15 at 16:44










    • how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
      – qodeninja
      Jul 28 at 20:47














    up vote
    11
    down vote



    accepted










    You can use branches:



    sed '
    1b1
    7b1
    14b1
    16b1

    # for the rest to be left alone, branch off (or delete them with "d"):
    b

    :1
    long_command'


    (note that you can also add some 20,25b1 line ranges, or /re/b1 to include lines that match the re).



    Or you could use awk:



    awk 'NR == 1 || NR == 7 || ... stuff'


    Or using a hash:



    awk -v l=1,7,14,16 '
    BEGINsplit(l, a, ","); for (i in a) lines[a[i]]

    NR in lines stuff'


    (or BEGINlines[1]lines[7]lines[14]lines[16] if there aren't too many)






    share|improve this answer






















    • Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
      – Weijun Zhou
      Jan 15 at 16:44










    • how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
      – qodeninja
      Jul 28 at 20:47












    up vote
    11
    down vote



    accepted







    up vote
    11
    down vote



    accepted






    You can use branches:



    sed '
    1b1
    7b1
    14b1
    16b1

    # for the rest to be left alone, branch off (or delete them with "d"):
    b

    :1
    long_command'


    (note that you can also add some 20,25b1 line ranges, or /re/b1 to include lines that match the re).



    Or you could use awk:



    awk 'NR == 1 || NR == 7 || ... stuff'


    Or using a hash:



    awk -v l=1,7,14,16 '
    BEGINsplit(l, a, ","); for (i in a) lines[a[i]]

    NR in lines stuff'


    (or BEGINlines[1]lines[7]lines[14]lines[16] if there aren't too many)






    share|improve this answer














    You can use branches:



    sed '
    1b1
    7b1
    14b1
    16b1

    # for the rest to be left alone, branch off (or delete them with "d"):
    b

    :1
    long_command'


    (note that you can also add some 20,25b1 line ranges, or /re/b1 to include lines that match the re).



    Or you could use awk:



    awk 'NR == 1 || NR == 7 || ... stuff'


    Or using a hash:



    awk -v l=1,7,14,16 '
    BEGINsplit(l, a, ","); for (i in a) lines[a[i]]

    NR in lines stuff'


    (or BEGINlines[1]lines[7]lines[14]lines[16] if there aren't too many)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 15 at 17:31

























    answered Jan 15 at 16:42









    Stéphane Chazelas

    281k53518849




    281k53518849











    • Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
      – Weijun Zhou
      Jan 15 at 16:44










    • how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
      – qodeninja
      Jul 28 at 20:47
















    • Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
      – Weijun Zhou
      Jan 15 at 16:44










    • how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
      – qodeninja
      Jul 28 at 20:47















    Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
    – Weijun Zhou
    Jan 15 at 16:44




    Thank you, never thought of branches ... It just seem to be the ideal tool to use in this case.
    – Weijun Zhou
    Jan 15 at 16:44












    how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
    – qodeninja
    Jul 28 at 20:47




    how do use branches like this in sed with a search pattern? like say I wanna match or delete a pattern after the nth line?
    – qodeninja
    Jul 28 at 20:47












    up vote
    3
    down vote













    Simply invert your selection and delete it:



    sed '2,6d;8,13d;15d;17,$d;long_command'





    share|improve this answer




















    • This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
      – Weijun Zhou
      Jan 15 at 17:08














    up vote
    3
    down vote













    Simply invert your selection and delete it:



    sed '2,6d;8,13d;15d;17,$d;long_command'





    share|improve this answer




















    • This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
      – Weijun Zhou
      Jan 15 at 17:08












    up vote
    3
    down vote










    up vote
    3
    down vote









    Simply invert your selection and delete it:



    sed '2,6d;8,13d;15d;17,$d;long_command'





    share|improve this answer












    Simply invert your selection and delete it:



    sed '2,6d;8,13d;15d;17,$d;long_command'






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 15 at 16:52









    Philippos

    5,90211545




    5,90211545











    • This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
      – Weijun Zhou
      Jan 15 at 17:08
















    • This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
      – Weijun Zhou
      Jan 15 at 17:08















    This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
    – Weijun Zhou
    Jan 15 at 17:08




    This is also a nice solution although a little harder for handling line numbers that are read from stdin, for example.
    – Weijun Zhou
    Jan 15 at 17:08










    up vote
    1
    down vote













    First variant:



    You can use this trick:



    sed -nf <(printf '%dpn' 1 7 14 16)



    -f script-file - add the contents of script-file to the commands to be executed.




    Testing



    seq 1 20 | sed -nf <(printf '%dpn' 1 7 14 16)


    Output



    1
    7
    14
    16


    Second variant:



    In the beginning, the auxiliary sed is used for filtering only needed lines from the file, then these lines piped to the main sed with the long command.



    sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'





    share|improve this answer


























      up vote
      1
      down vote













      First variant:



      You can use this trick:



      sed -nf <(printf '%dpn' 1 7 14 16)



      -f script-file - add the contents of script-file to the commands to be executed.




      Testing



      seq 1 20 | sed -nf <(printf '%dpn' 1 7 14 16)


      Output



      1
      7
      14
      16


      Second variant:



      In the beginning, the auxiliary sed is used for filtering only needed lines from the file, then these lines piped to the main sed with the long command.



      sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'





      share|improve this answer
























        up vote
        1
        down vote










        up vote
        1
        down vote









        First variant:



        You can use this trick:



        sed -nf <(printf '%dpn' 1 7 14 16)



        -f script-file - add the contents of script-file to the commands to be executed.




        Testing



        seq 1 20 | sed -nf <(printf '%dpn' 1 7 14 16)


        Output



        1
        7
        14
        16


        Second variant:



        In the beginning, the auxiliary sed is used for filtering only needed lines from the file, then these lines piped to the main sed with the long command.



        sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'





        share|improve this answer














        First variant:



        You can use this trick:



        sed -nf <(printf '%dpn' 1 7 14 16)



        -f script-file - add the contents of script-file to the commands to be executed.




        Testing



        seq 1 20 | sed -nf <(printf '%dpn' 1 7 14 16)


        Output



        1
        7
        14
        16


        Second variant:



        In the beginning, the auxiliary sed is used for filtering only needed lines from the file, then these lines piped to the main sed with the long command.



        sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 16 at 19:26

























        answered Jan 16 at 18:44









        MiniMax

        2,686718




        2,686718






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f417284%2fperform-sed-operations-on-given-line-numbers%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)