Removing trailing / starting newlines with sed, awk, tr, and friends

后端 未结 16 655
一个人的身影
一个人的身影 2021-01-30 21:04

I would like to remove all of the empty lines from a file, but only when they are at the end/start of a file (that is, if there are no non-empty lines before them, at the start;

相关标签:
16条回答
  • 2021-01-30 21:18
    perl -0pe 's/^\n+|\n+(\n)$/\1/gs'
    
    0 讨论(0)
  • 2021-01-30 21:19

    Here's an adapted sed version, which also considers "empty" those lines with just spaces and tabs on it.

    sed -e :a -e '/[^[:blank:]]/,$!d; /^[[:space:]]*$/{ $d; N; ba' -e '}'
    

    It's basically the accepted answer version (considering BryanH comment), but the dot . in the first command was changed to [^[:blank:]] (anything not blank) and the \n inside the second command address was changed to [[:space:]] to allow newlines, spaces an tabs.

    An alternative version, without using the POSIX classes, but your sed must support inserting \t and \n inside […]. GNU sed does, BSD sed doesn't.

    sed -e :a -e '/[^\t ]/,$!d; /^[\n\t ]*$/{ $d; N; ba' -e '}'
    

    Testing:

    prompt$ printf '\n \t \n\nfoo\n\nfoo\n\n \t \n\n' 
    
    
    
    foo
    
    foo
    
    
    
    prompt$ printf '\n \t \n\nfoo\n\nfoo\n\n \t \n\n' | sed -n l
    $
     \t $
    $
    foo$
    $
    foo$
    $
     \t $
    $
    prompt$ printf '\n \t \n\nfoo\n\nfoo\n\n \t \n\n' | sed -e :a -e '/[^[:blank:]]/,$!d; /^[[:space:]]*$/{ $d; N; ba' -e '}'
    foo
    
    foo
    prompt$
    
    0 讨论(0)
  • 2021-01-30 21:20

    @dogbane has a nice simple answer for removing leading empty lines. Here's a simple awk command which removes just the trailing lines. Use this with @dogbane's sed command to remove both leading and trailing blanks.

    awk '{ LINES=LINES $0 "\n"; } /./ { printf "%s", LINES; LINES=""; }'
    

    This is pretty simple in operation.

    • Add every line to a buffer as we read it.
    • For every line which contains a character, print the contents of the buffer and then clear it.

    So the only things that get buffered and never displayed are any trailing blanks.

    I used printf instead of print to avoid the automatic addition of a newline, since I'm using newlines to separate the lines in the buffer already.

    0 讨论(0)
  • 2021-01-30 21:21

    using awk:

    awk '{a[NR]=$0;if($0 && !s)s=NR;}
        END{e=NR;
            for(i=NR;i>1;i--) 
                if(a[i]){ e=i; break; } 
            for(i=s;i<=e;i++)
                print a[i];}' yourFile
    
    0 讨论(0)
  • 2021-01-30 21:21

    this can be solved easily with sed -z option

    sed -rz 's/^\n+//; s/\n+$/\n/g' file
    Hello
    
    Welcome to
    Unix and Linux
    
    0 讨论(0)
  • 2021-01-30 21:23

    here's a one-pass solution in awk: it does not start printing until it sees a non-empty line and when it sees an empty line, it remembers it until the next non-empty line

    awk '
        /[[:graph:]]/ {
            # a non-empty line
            # set the flag to begin printing lines
            p=1      
            # print the accumulated "interior" empty lines 
            for (i=1; i<=n; i++) print ""
            n=0
            # then print this line
            print
        }
        p && /^[[:space:]]*$/ {
            # a potentially "interior" empty line. remember it.
            n++
        }
    ' filename
    

    Note, due to the mechanism I'm using to consider empty/non-empty lines (with [[:graph:]] and /^[[:space:]]*$/), interior lines with only whitespace will be truncated to become truly empty.

    0 讨论(0)
提交回复
热议问题