Grep lines but let the first line through

1,278

Solution 1

I would use a slightly more sophisticated approach than simple grep:

  1. awk

    df -h | awk 'NR==1 || /^\/dev/'
    

    NR is the current line number so the awk scriptlet above will print if this is the first line or if the current line begins with /dev. And after posting this I see it is the same as @1_CR's answer. Oh well...

  2. Perl

    df -h | perl -ne 'print if (/^\/dev/ || $.==1)'
    

    The same idea here, in Perl the special variable $. is the current line number. An alternative way would be

    df -h | perl -pe '$_="" unless /^\/dev/ || $.==1'
    

    The -p switch will print all lines of the input file. The value of the current line is held in $_ so we set $_ to empty unless we want the current line.

  3. sed

    df -h | sed -n '1p; /^\/dev/p'
    

    The -n suppresses normal output so no lines are printed. The 1p means print the first line and the /^\/dev/p means print any line that starts with /dev.

    As pointed out in the comments below, in the unlikely case where the locale on your current system causes the header line to start with /dev, the command above will print it twice. Stephane Chazelas points out that this one will not have that problem:

    df -h | sed  -e 1b -e '/^\/dev/!d'
    
  4. grep

    df -h | grep -E '^(/dev|File)'
    

    This might not be portable because of LOCALE problems as you said. However, I am reasonably certain that no locale or df version will give a path in the first line, so searching for lines that contain no / should also work:

    df -h | grep -E '^[^/]*$|^/dev'
    

Solution 2

You are going to run into issues attempting to parse df output, however for simple cases, the following may work

LC_ALL=C df -P | awk 'NR == 1 || /^\/dev/' 

Solution 3

This should work as well (not tested, though):

df | (read a; echo "$a"; grep /dev)

or

df | (head -n 1; grep ^/dev)

Solution 4

df -h | tee >(head -1) >(sleep 0.5;grep ^/dev) > /dev/null;sleep 1.0

Solution 5

df | head -n 1; df | grep ^/dev
Share:
1,278

Related videos on Youtube

John Ryan
Author by

John Ryan

Updated on September 18, 2022

Comments

  • John Ryan
    John Ryan over 1 year

    So,

    I'm trying Facebook.api("/me/friends?fields=installed",handleFunc); with no joy, I get a bad request error in Firebug.

    However, I have no problem getting just a list of friends: Facebook.api("/me/friends", handleFriendsLoad);

    I know there is a FQL way of doing this. But, why does the above not work for me? If FQL is the only way of doing this, what is the code needed?

    Many thanks

    • Totor
      Totor over 10 years
      locale dependant maybe, but your can force the language with LANG=C df.
    • terdon
      terdon over 10 years
      @Totor see 1_CR's answer, that's exactly what he suggested.
    • Mikel
      Mikel over 10 years
      This has been answered several times previously. See e.g. body from unix.stackexchange.com/a/11859/3169
  • Jashwant
    Jashwant about 12 years
    Mark as answer if it helps you :)
  • Stéphane Chazelas
    Stéphane Chazelas over 10 years
    Your sed one would print the 1st line twice if it started with /dev. Unlikely, but sed -e 1b -e '/^\/dev/!d' wouldn't have the problem.
  • Keith Thompson
    Keith Thompson over 10 years
    I just tried that; it printed the header line first.
  • Keith Thompson
    Keith Thompson over 10 years
    Not bad, but it has the disadvantage that it invokes df twice.
  • Keith Thompson
    Keith Thompson over 10 years
    Not particularly, but there are solutions like terdon's df -h | sed -e 1b -e '/^\/dev/!d' that only invoke df once. The df command can hang in some circumstances; in that case, invoking it just once is probably better.
  • l0b0
    l0b0 over 10 years
    @KeithThompson Why is that a problem? The accepted answers also print the header line first.
  • Keith Thompson
    Keith Thompson over 10 years
    @l0b0: Sorry, I mistyped; it printed the header line last.
  • terdon
    terdon over 10 years
    Nice trick but it will not work as expected if you are mounting by UUID instead of device name. The OP wants df style output which means /dev/foo your command will return /dev/disk/by-uuid/ format output unless fstab contains the /dev name.
  • mahendra yadav
    mahendra yadav over 10 years
    Worked correcly on my machine. Try df -h | tee >(head -1) >(sleep 0.5;grep ^/dev) > /dev/null;sleep 1.0
  • Chaim Geretz
    Chaim Geretz over 10 years
    very nice. ^/dev will limit this to lines that start with /dev. Wasn't able to do that as an an edit since I was short 9 characters
  • derobert
    derobert over 10 years
    OP has said the heading is locale-dependent, so you can't match it like that. And what is the sda1 doing at the end?
  • LovelyI
    LovelyI over 10 years
    The mount command uses /etc/mtab, which is updated dynamically, and while I am not sure where df gets its data from, I suspect that on Linux it reads /proc/mounts. Either way I don't understand how fstab is relevant and could not reproduce the problem with UUID-mounted disks. Can you elaborate on it?
  • derobert
    derobert over 9 years
    @syntaxerror the heading is locale-dependent, as is sorting. So that won't work either, for the same reason. Try LANGUAGE=ja df -h, for example. Or Spanish, or French, or many others.
  • mahendra yadav
    mahendra yadav over 8 years
    Anonymous edited my post and it does not work for me. df -h | tee >(head -n 1) | grep ^/dev
  • steveayre
    steveayre over 8 years
    First one works, but you should echo "$a" (note quotes) or any spacing in the header will shrink down to single spaces (eg with column aligned output). Second one does not.
  • bnikhil
    bnikhil over 8 years
    @steveayre Thanks for the suggestion. Integrated it into answer.
  • pabouk - Ukraine stay strong
    pabouk - Ukraine stay strong over 4 years
    @steveayre even echo "$a" is not completely safe (possible different interpretation of - or \ ). It is always better to use printf %s\\n "$a" to print a string which could possibly contain the mentioned characters.