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

后端 未结 16 657
一个人的身影
一个人的身影 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:36

    So I'm going to borrow part of @dogbane's answer for this, since that sed line for removing the leading blank lines is so short...

    tac is part of coreutils, and reverses a file. So do it twice:

    tac file | sed -e '/./,$!d' | tac | sed -e '/./,$!d'
    

    It's certainly not the most efficient, but unless you need efficiency, I find it more readable than everything else so far.

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

    I'd like to introduce another variant for gawk v4.1+

    result=($(gawk '
        BEGIN {
            lines_count         = 0;
            empty_lines_in_head = 0;
            empty_lines_in_tail = 0;
        }
        /[^[:space:]]/ {
            found_not_empty_line = 1;
            empty_lines_in_tail  = 0;
        }
        /^[[:space:]]*?$/ {
            if ( found_not_empty_line ) {
                empty_lines_in_tail ++;
            } else {
                empty_lines_in_head ++;
            }
        }
        {
            lines_count ++;
        }
        END {
            print (empty_lines_in_head " " empty_lines_in_tail " " lines_count);
        }
    ' "$file"))
    
    empty_lines_in_head=${result[0]}
    empty_lines_in_tail=${result[1]}
    lines_count=${result[2]}
    
    if [ $empty_lines_in_head -gt 0 ] || [ $empty_lines_in_tail -gt 0 ]; then
        echo "Removing whitespace from \"$file\""
        eval "gawk -i inplace '
            {
                if ( NR > $empty_lines_in_head && NR <= $(($lines_count - $empty_lines_in_tail)) ) {
                    print
                }
            }
        ' \"$file\""
    fi
    
    0 讨论(0)
  • 2021-01-30 21:40

    In bash, using cat, wc, grep, sed, tail and head:

    # number of first line that contains non-empty character
    i=`grep -n "^[^\B*]" <your_file> | sed -e 's/:.*//' | head -1`
    # number of hte last one
    j=`grep -n "^[^\B*]" <your_file> | sed -e 's/:.*//' | tail -1`
    # overall number of lines:
    k=`cat <your_file> | wc -l`
    # how much empty lines at the end of file we have?
    m=$(($k-$j))
    # let strip last m lines!
    cat <your_file> | head -n-$m
    # now we have to strip first i lines and we are done 8-)
    cat <your_file> | tail -n+$i
    

    Man, it's definitely worth to learn "real" programming language to avoid that ugliness!

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

    This AWK script will do the trick:

    BEGIN {
        ne=0;
    }
    
    /^[[:space:]]*$/ {
        ne++;
    }
    
    /[^[:space:]]+/ {
        for(i=0; i < ne; i++)
            print "";
        ne=0;
        print
    }
    

    The idea is simple: empty lines do not get echoed immediately. Instead, we wait till we get a non-empty line, and only then we first echo out as much empty lines as seen before it, and only then echo out the new non-empty line.

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