get a percentage of a file

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











up vote
2
down vote

favorite
3












Is there a linux command to return the last x % of a file? I know tail can return a number of lines (-n) or number of bytes (-c), but what if I wanted to get the last 25% of a file? Is there a command to do that?







share|improve this question
















  • 4




    No, but you can use wc to get a line/char count of the whole file, perform your own calculation, then pass the resulting value to tail
    – glenn jackman
    Jan 5 at 19:20






  • 2




    If you just want to view the last x %, then you could use less with a per-cent offset e.g.less +p75 somefile
    – steeldriver
    Jan 5 at 19:57














up vote
2
down vote

favorite
3












Is there a linux command to return the last x % of a file? I know tail can return a number of lines (-n) or number of bytes (-c), but what if I wanted to get the last 25% of a file? Is there a command to do that?







share|improve this question
















  • 4




    No, but you can use wc to get a line/char count of the whole file, perform your own calculation, then pass the resulting value to tail
    – glenn jackman
    Jan 5 at 19:20






  • 2




    If you just want to view the last x %, then you could use less with a per-cent offset e.g.less +p75 somefile
    – steeldriver
    Jan 5 at 19:57












up vote
2
down vote

favorite
3









up vote
2
down vote

favorite
3






3





Is there a linux command to return the last x % of a file? I know tail can return a number of lines (-n) or number of bytes (-c), but what if I wanted to get the last 25% of a file? Is there a command to do that?







share|improve this question












Is there a linux command to return the last x % of a file? I know tail can return a number of lines (-n) or number of bytes (-c), but what if I wanted to get the last 25% of a file? Is there a command to do that?









share|improve this question











share|improve this question




share|improve this question










asked Jan 5 at 19:09









raphael75

1468




1468







  • 4




    No, but you can use wc to get a line/char count of the whole file, perform your own calculation, then pass the resulting value to tail
    – glenn jackman
    Jan 5 at 19:20






  • 2




    If you just want to view the last x %, then you could use less with a per-cent offset e.g.less +p75 somefile
    – steeldriver
    Jan 5 at 19:57












  • 4




    No, but you can use wc to get a line/char count of the whole file, perform your own calculation, then pass the resulting value to tail
    – glenn jackman
    Jan 5 at 19:20






  • 2




    If you just want to view the last x %, then you could use less with a per-cent offset e.g.less +p75 somefile
    – steeldriver
    Jan 5 at 19:57







4




4




No, but you can use wc to get a line/char count of the whole file, perform your own calculation, then pass the resulting value to tail
– glenn jackman
Jan 5 at 19:20




No, but you can use wc to get a line/char count of the whole file, perform your own calculation, then pass the resulting value to tail
– glenn jackman
Jan 5 at 19:20




2




2




If you just want to view the last x %, then you could use less with a per-cent offset e.g.less +p75 somefile
– steeldriver
Jan 5 at 19:57




If you just want to view the last x %, then you could use less with a per-cent offset e.g.less +p75 somefile
– steeldriver
Jan 5 at 19:57










3 Answers
3






active

oldest

votes

















up vote
13
down vote



accepted










GNU split can do pretty much what you ask; given a text file in.txt, this will print the last quarter (part 4 out of 4) in terms of number of bytes (not lines), without splitting lines:



split -n l/4/4 in.txt


Here is the relevant documentation for split -n CHUNKS:




CHUNKS may be: [...] l/K/N output Kth of N to stdout without
splitting lines




In the very specific case mentioned as an example in the question,
4/4 requests the fourth quarter, or the last 25% of the input
file. For sizes that are not 1/n of the input, I do not think split
provides such a straightforward solution.






share|improve this answer






















  • That will work. Thank you!
    – raphael75
    Jan 5 at 19:29

















up vote
5
down vote













Complex bash + stat + bc + tail solution for any percentage:



get_last_chunk () 
local p=$(bc <<<"scale=2; $1/100")
tail -c $(printf "%.0f" $(echo "$(stat -c%s $2) * $p"




  • $1 and $2 - are the function's 1st and 2nd arguments respectively


  • p - variable assigned with percentage value as float number (for ex. 0.14 or 0.55)


  • stat -c%s $2 - getting the actual size of the input file in bytes


  • tail -c N $2 - getting the last N bytes of the file


Or use the more simplified version:



get_last_chunk () 
tail -c "$(($(stat -c%s - < "$2") * $1 / 100))" < "$2"))"



Signature: get_last_chunk <percent> <filename>



Sample file.txt:



apples
oranges
bananas
cherries



Test cases:



get_last_chunk 17 file.txt
ries



get_last_chunk 77 file.txt
oranges
bananas
cherries



get_last_chunk 29 file.txt
cherries





share|improve this answer






















  • I like the creativity of this one. :)
    – raphael75
    Jan 5 at 19:52










  • You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
    – CSM
    Jan 5 at 23:07






  • 1




    echo expression | bc is a useless use of echo. We can instead bc <<< expression.
    – user137369
    Jan 6 at 2:15











  • @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
    – Stéphane Chazelas
    Jan 6 at 10:30







  • 1




    @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
    – Stéphane Chazelas
    Jan 6 at 17:39


















up vote
0
down vote













To get the last $1% in terms of number of lines, portably (POSIXly):



last_percent() (
percent=$1?; shift
ret=0
for file do
lines=$(wc -l < "$file") &&
tail -n "$((lines * percent / 100))" < "$file" || ret=$?
done
exit "$ret"
)


Example:



$ seq 12 > a; printf '%sn' aaaaaa bbbbb cccc dd > b
$ last_percent 25 a b
10
11
12
dd


For the last $1% in terms of number of bytes, replace wc -l with wc -c and tail -n with tail -c. Beware though that the first output line would likely be partial. On the same files as above, that would give:



$ last_percent 25 a b
11
12
c
dd


With ksh93, you could write it with only builtins and not a single fork as:



last_percent() (
percent=$1; shift
ret=0
for file do
command /opt/ast/bin/cat < "$file" <#((EOF*(100-percent)/100)) || ret=$?
done
exit "$ret"
)


Using its <#((...)) seeking operator.



The same with zsh (except that cat is not builtin there):



zmodload zsh/system zsh/stat
last_percent() ret=$?
done
return $ret






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%2f415057%2fget-a-percentage-of-a-file%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
    13
    down vote



    accepted










    GNU split can do pretty much what you ask; given a text file in.txt, this will print the last quarter (part 4 out of 4) in terms of number of bytes (not lines), without splitting lines:



    split -n l/4/4 in.txt


    Here is the relevant documentation for split -n CHUNKS:




    CHUNKS may be: [...] l/K/N output Kth of N to stdout without
    splitting lines




    In the very specific case mentioned as an example in the question,
    4/4 requests the fourth quarter, or the last 25% of the input
    file. For sizes that are not 1/n of the input, I do not think split
    provides such a straightforward solution.






    share|improve this answer






















    • That will work. Thank you!
      – raphael75
      Jan 5 at 19:29














    up vote
    13
    down vote



    accepted










    GNU split can do pretty much what you ask; given a text file in.txt, this will print the last quarter (part 4 out of 4) in terms of number of bytes (not lines), without splitting lines:



    split -n l/4/4 in.txt


    Here is the relevant documentation for split -n CHUNKS:




    CHUNKS may be: [...] l/K/N output Kth of N to stdout without
    splitting lines




    In the very specific case mentioned as an example in the question,
    4/4 requests the fourth quarter, or the last 25% of the input
    file. For sizes that are not 1/n of the input, I do not think split
    provides such a straightforward solution.






    share|improve this answer






















    • That will work. Thank you!
      – raphael75
      Jan 5 at 19:29












    up vote
    13
    down vote



    accepted







    up vote
    13
    down vote



    accepted






    GNU split can do pretty much what you ask; given a text file in.txt, this will print the last quarter (part 4 out of 4) in terms of number of bytes (not lines), without splitting lines:



    split -n l/4/4 in.txt


    Here is the relevant documentation for split -n CHUNKS:




    CHUNKS may be: [...] l/K/N output Kth of N to stdout without
    splitting lines




    In the very specific case mentioned as an example in the question,
    4/4 requests the fourth quarter, or the last 25% of the input
    file. For sizes that are not 1/n of the input, I do not think split
    provides such a straightforward solution.






    share|improve this answer














    GNU split can do pretty much what you ask; given a text file in.txt, this will print the last quarter (part 4 out of 4) in terms of number of bytes (not lines), without splitting lines:



    split -n l/4/4 in.txt


    Here is the relevant documentation for split -n CHUNKS:




    CHUNKS may be: [...] l/K/N output Kth of N to stdout without
    splitting lines




    In the very specific case mentioned as an example in the question,
    4/4 requests the fourth quarter, or the last 25% of the input
    file. For sizes that are not 1/n of the input, I do not think split
    provides such a straightforward solution.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 6 at 9:15









    Stéphane Chazelas

    281k53518849




    281k53518849










    answered Jan 5 at 19:23









    dhag

    10.7k32642




    10.7k32642











    • That will work. Thank you!
      – raphael75
      Jan 5 at 19:29
















    • That will work. Thank you!
      – raphael75
      Jan 5 at 19:29















    That will work. Thank you!
    – raphael75
    Jan 5 at 19:29




    That will work. Thank you!
    – raphael75
    Jan 5 at 19:29












    up vote
    5
    down vote













    Complex bash + stat + bc + tail solution for any percentage:



    get_last_chunk () 
    local p=$(bc <<<"scale=2; $1/100")
    tail -c $(printf "%.0f" $(echo "$(stat -c%s $2) * $p"




    • $1 and $2 - are the function's 1st and 2nd arguments respectively


    • p - variable assigned with percentage value as float number (for ex. 0.14 or 0.55)


    • stat -c%s $2 - getting the actual size of the input file in bytes


    • tail -c N $2 - getting the last N bytes of the file


    Or use the more simplified version:



    get_last_chunk () 
    tail -c "$(($(stat -c%s - < "$2") * $1 / 100))" < "$2"))"



    Signature: get_last_chunk <percent> <filename>



    Sample file.txt:



    apples
    oranges
    bananas
    cherries



    Test cases:



    get_last_chunk 17 file.txt
    ries



    get_last_chunk 77 file.txt
    oranges
    bananas
    cherries



    get_last_chunk 29 file.txt
    cherries





    share|improve this answer






















    • I like the creativity of this one. :)
      – raphael75
      Jan 5 at 19:52










    • You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
      – CSM
      Jan 5 at 23:07






    • 1




      echo expression | bc is a useless use of echo. We can instead bc <<< expression.
      – user137369
      Jan 6 at 2:15











    • @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
      – Stéphane Chazelas
      Jan 6 at 10:30







    • 1




      @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
      – Stéphane Chazelas
      Jan 6 at 17:39















    up vote
    5
    down vote













    Complex bash + stat + bc + tail solution for any percentage:



    get_last_chunk () 
    local p=$(bc <<<"scale=2; $1/100")
    tail -c $(printf "%.0f" $(echo "$(stat -c%s $2) * $p"




    • $1 and $2 - are the function's 1st and 2nd arguments respectively


    • p - variable assigned with percentage value as float number (for ex. 0.14 or 0.55)


    • stat -c%s $2 - getting the actual size of the input file in bytes


    • tail -c N $2 - getting the last N bytes of the file


    Or use the more simplified version:



    get_last_chunk () 
    tail -c "$(($(stat -c%s - < "$2") * $1 / 100))" < "$2"))"



    Signature: get_last_chunk <percent> <filename>



    Sample file.txt:



    apples
    oranges
    bananas
    cherries



    Test cases:



    get_last_chunk 17 file.txt
    ries



    get_last_chunk 77 file.txt
    oranges
    bananas
    cherries



    get_last_chunk 29 file.txt
    cherries





    share|improve this answer






















    • I like the creativity of this one. :)
      – raphael75
      Jan 5 at 19:52










    • You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
      – CSM
      Jan 5 at 23:07






    • 1




      echo expression | bc is a useless use of echo. We can instead bc <<< expression.
      – user137369
      Jan 6 at 2:15











    • @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
      – Stéphane Chazelas
      Jan 6 at 10:30







    • 1




      @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
      – Stéphane Chazelas
      Jan 6 at 17:39













    up vote
    5
    down vote










    up vote
    5
    down vote









    Complex bash + stat + bc + tail solution for any percentage:



    get_last_chunk () 
    local p=$(bc <<<"scale=2; $1/100")
    tail -c $(printf "%.0f" $(echo "$(stat -c%s $2) * $p"




    • $1 and $2 - are the function's 1st and 2nd arguments respectively


    • p - variable assigned with percentage value as float number (for ex. 0.14 or 0.55)


    • stat -c%s $2 - getting the actual size of the input file in bytes


    • tail -c N $2 - getting the last N bytes of the file


    Or use the more simplified version:



    get_last_chunk () 
    tail -c "$(($(stat -c%s - < "$2") * $1 / 100))" < "$2"))"



    Signature: get_last_chunk <percent> <filename>



    Sample file.txt:



    apples
    oranges
    bananas
    cherries



    Test cases:



    get_last_chunk 17 file.txt
    ries



    get_last_chunk 77 file.txt
    oranges
    bananas
    cherries



    get_last_chunk 29 file.txt
    cherries





    share|improve this answer














    Complex bash + stat + bc + tail solution for any percentage:



    get_last_chunk () 
    local p=$(bc <<<"scale=2; $1/100")
    tail -c $(printf "%.0f" $(echo "$(stat -c%s $2) * $p"




    • $1 and $2 - are the function's 1st and 2nd arguments respectively


    • p - variable assigned with percentage value as float number (for ex. 0.14 or 0.55)


    • stat -c%s $2 - getting the actual size of the input file in bytes


    • tail -c N $2 - getting the last N bytes of the file


    Or use the more simplified version:



    get_last_chunk () 
    tail -c "$(($(stat -c%s - < "$2") * $1 / 100))" < "$2"))"



    Signature: get_last_chunk <percent> <filename>



    Sample file.txt:



    apples
    oranges
    bananas
    cherries



    Test cases:



    get_last_chunk 17 file.txt
    ries



    get_last_chunk 77 file.txt
    oranges
    bananas
    cherries



    get_last_chunk 29 file.txt
    cherries






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 6 at 12:25

























    answered Jan 5 at 19:48









    RomanPerekhrest

    22.4k12145




    22.4k12145











    • I like the creativity of this one. :)
      – raphael75
      Jan 5 at 19:52










    • You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
      – CSM
      Jan 5 at 23:07






    • 1




      echo expression | bc is a useless use of echo. We can instead bc <<< expression.
      – user137369
      Jan 6 at 2:15











    • @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
      – Stéphane Chazelas
      Jan 6 at 10:30







    • 1




      @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
      – Stéphane Chazelas
      Jan 6 at 17:39

















    • I like the creativity of this one. :)
      – raphael75
      Jan 5 at 19:52










    • You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
      – CSM
      Jan 5 at 23:07






    • 1




      echo expression | bc is a useless use of echo. We can instead bc <<< expression.
      – user137369
      Jan 6 at 2:15











    • @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
      – Stéphane Chazelas
      Jan 6 at 10:30







    • 1




      @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
      – Stéphane Chazelas
      Jan 6 at 17:39
















    I like the creativity of this one. :)
    – raphael75
    Jan 5 at 19:52




    I like the creativity of this one. :)
    – raphael75
    Jan 5 at 19:52












    You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
    – CSM
    Jan 5 at 23:07




    You are probably better using stat -c%s filename.txt to get the filesize, rather than wc. stat will call fstat (or similar) to ask the fs driver for the filesize, rather than scanning the whole file.
    – CSM
    Jan 5 at 23:07




    1




    1




    echo expression | bc is a useless use of echo. We can instead bc <<< expression.
    – user137369
    Jan 6 at 2:15





    echo expression | bc is a useless use of echo. We can instead bc <<< expression.
    – user137369
    Jan 6 at 2:15













    @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
    – Stéphane Chazelas
    Jan 6 at 10:30





    @user137369, <<< means creating a temporary files filling it with the text, make that the stdin of the command and delete it. Whether it's better or worse than using the builtin echo with a pipe is up for debate. That also adds a requirement on the system having a zsh-like shell. But here, you don't use bc (nor printf) at all, you can use shell arithmetic expression.
    – Stéphane Chazelas
    Jan 6 at 10:30





    1




    1




    @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
    – Stéphane Chazelas
    Jan 6 at 17:39





    @user137369, here documents and here strings in bash are implemented with deleted temporary files like they were in the Bourne shell (which didn't have herestrings, just heredocs, herestrings come from zsh, so bash is a zsh-like shell in that regard)
    – Stéphane Chazelas
    Jan 6 at 17:39











    up vote
    0
    down vote













    To get the last $1% in terms of number of lines, portably (POSIXly):



    last_percent() (
    percent=$1?; shift
    ret=0
    for file do
    lines=$(wc -l < "$file") &&
    tail -n "$((lines * percent / 100))" < "$file" || ret=$?
    done
    exit "$ret"
    )


    Example:



    $ seq 12 > a; printf '%sn' aaaaaa bbbbb cccc dd > b
    $ last_percent 25 a b
    10
    11
    12
    dd


    For the last $1% in terms of number of bytes, replace wc -l with wc -c and tail -n with tail -c. Beware though that the first output line would likely be partial. On the same files as above, that would give:



    $ last_percent 25 a b
    11
    12
    c
    dd


    With ksh93, you could write it with only builtins and not a single fork as:



    last_percent() (
    percent=$1; shift
    ret=0
    for file do
    command /opt/ast/bin/cat < "$file" <#((EOF*(100-percent)/100)) || ret=$?
    done
    exit "$ret"
    )


    Using its <#((...)) seeking operator.



    The same with zsh (except that cat is not builtin there):



    zmodload zsh/system zsh/stat
    last_percent() ret=$?
    done
    return $ret






    share|improve this answer


























      up vote
      0
      down vote













      To get the last $1% in terms of number of lines, portably (POSIXly):



      last_percent() (
      percent=$1?; shift
      ret=0
      for file do
      lines=$(wc -l < "$file") &&
      tail -n "$((lines * percent / 100))" < "$file" || ret=$?
      done
      exit "$ret"
      )


      Example:



      $ seq 12 > a; printf '%sn' aaaaaa bbbbb cccc dd > b
      $ last_percent 25 a b
      10
      11
      12
      dd


      For the last $1% in terms of number of bytes, replace wc -l with wc -c and tail -n with tail -c. Beware though that the first output line would likely be partial. On the same files as above, that would give:



      $ last_percent 25 a b
      11
      12
      c
      dd


      With ksh93, you could write it with only builtins and not a single fork as:



      last_percent() (
      percent=$1; shift
      ret=0
      for file do
      command /opt/ast/bin/cat < "$file" <#((EOF*(100-percent)/100)) || ret=$?
      done
      exit "$ret"
      )


      Using its <#((...)) seeking operator.



      The same with zsh (except that cat is not builtin there):



      zmodload zsh/system zsh/stat
      last_percent() ret=$?
      done
      return $ret






      share|improve this answer
























        up vote
        0
        down vote










        up vote
        0
        down vote









        To get the last $1% in terms of number of lines, portably (POSIXly):



        last_percent() (
        percent=$1?; shift
        ret=0
        for file do
        lines=$(wc -l < "$file") &&
        tail -n "$((lines * percent / 100))" < "$file" || ret=$?
        done
        exit "$ret"
        )


        Example:



        $ seq 12 > a; printf '%sn' aaaaaa bbbbb cccc dd > b
        $ last_percent 25 a b
        10
        11
        12
        dd


        For the last $1% in terms of number of bytes, replace wc -l with wc -c and tail -n with tail -c. Beware though that the first output line would likely be partial. On the same files as above, that would give:



        $ last_percent 25 a b
        11
        12
        c
        dd


        With ksh93, you could write it with only builtins and not a single fork as:



        last_percent() (
        percent=$1; shift
        ret=0
        for file do
        command /opt/ast/bin/cat < "$file" <#((EOF*(100-percent)/100)) || ret=$?
        done
        exit "$ret"
        )


        Using its <#((...)) seeking operator.



        The same with zsh (except that cat is not builtin there):



        zmodload zsh/system zsh/stat
        last_percent() ret=$?
        done
        return $ret






        share|improve this answer














        To get the last $1% in terms of number of lines, portably (POSIXly):



        last_percent() (
        percent=$1?; shift
        ret=0
        for file do
        lines=$(wc -l < "$file") &&
        tail -n "$((lines * percent / 100))" < "$file" || ret=$?
        done
        exit "$ret"
        )


        Example:



        $ seq 12 > a; printf '%sn' aaaaaa bbbbb cccc dd > b
        $ last_percent 25 a b
        10
        11
        12
        dd


        For the last $1% in terms of number of bytes, replace wc -l with wc -c and tail -n with tail -c. Beware though that the first output line would likely be partial. On the same files as above, that would give:



        $ last_percent 25 a b
        11
        12
        c
        dd


        With ksh93, you could write it with only builtins and not a single fork as:



        last_percent() (
        percent=$1; shift
        ret=0
        for file do
        command /opt/ast/bin/cat < "$file" <#((EOF*(100-percent)/100)) || ret=$?
        done
        exit "$ret"
        )


        Using its <#((...)) seeking operator.



        The same with zsh (except that cat is not builtin there):



        zmodload zsh/system zsh/stat
        last_percent() ret=$?
        done
        return $ret







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 6 at 11:04

























        answered Jan 6 at 9:19









        Stéphane Chazelas

        281k53518849




        281k53518849






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f415057%2fget-a-percentage-of-a-file%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)