45

ファイルからすべての空の行を削除したいのですが、それらがファイルの最後/最初にある場合(つまり、前に空でない行がない場合、最初にある場合、およびある場合)に限ります。最後に、それらの後に空でない行はありません。)

これは、PerlやRubyのようなフル機能のスクリプト言語の外で可能ですか?可能であれば、sedまたは可能であればこれを実行したいと思います。awk基本的に、軽量で広く利用可能なUNIX-yツールであれば問題ありません。特に、私がすぐに詳しく知ることができるツールです(Perl、したがって含まれていません)。

4

17 に答える 17

64

sed の便利な1行スクリプトから:

# Delete all leading blank lines at top of file (only).
sed '/./,$!d' file

# Delete all trailing blank lines at end of file (only).
sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba' file

したがって、ファイルから先頭と末尾の両方の空白行を削除するには、上記のコマンドを次のように組み合わせることができます。

sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba' file
于 2011-09-09T09:52:40.697 に答える
6

別の回答で述べたようにtac、 coreutils の一部であり、ファイルを逆にします。コマンド置換が末尾の新しい行を削除するという事実とそれを 2 回行うという考えを組み合わせると、次のようになります。

echo "$(echo "$(tac "$filename")" | tac)"

に依存しませんsedecho -n残りの末尾の改行を取り除くために使用できます。

于 2014-07-07T12:35:58.013 に答える
6

awk のワンパス ソリューションは次のとおりです。空でない行が表示されるまで印刷を開始せず、空行が表示されると、次の空でない行までそれを記憶します。

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

空行/非空行を考慮するために使用しているメカニズム ( と[[:graph:]]を使用/^[[:space:]]*$/) により、空白のみの内部行は切り捨てられて真に空になることに注意してください。

于 2011-09-09T14:42:31.670 に答える
4

これは、スペースとタブだけの行を「空」と見なす、適応された sed バージョンです。

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

これは基本的に受け入れられた回答バージョンです(BryanHコメントを考慮)が.、最初のコマンドのドットは[^[:blank:]](空白ではないもの)\nに変更され、2番目のコマンドアドレス内は[[:space:]]改行、スペース、タブを許可するように変更されました.

POSIX クラスを使用しない代替バージョンですが、sed は insert\t\ninsideをサポートする必要があります[…]。GNU sed にはありますが、BSD sed にはありません。

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

テスト:

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$
于 2015-03-05T14:58:01.763 に答える
2

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
于 2011-09-09T09:42:36.230 に答える
1

使用するbash

$ filecontent=$(<file)
$ echo "${filecontent/$'\n'}"
于 2011-09-09T09:38:21.067 に答える
1

bash では、cat、wc、grep、sed、tail、および 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

その醜さを避けるために、「本物の」プログラミング言語を学ぶことは間違いなく価値があります!

于 2011-09-09T09:36:22.773 に答える
0

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
于 2014-11-02T18:07:01.670 に答える
0

とにかくいくつかの関数を含むスクリプトを書いていたのでbash、それらを書くと便利であることがわかりました:

function strip_leading_empty_lines()
{
    while read line; do
        if [ -n "$line" ]; then
            echo "$line"
            break
        fi
    done
    cat
}

function strip_trailing_empty_lines()
{
    acc=""
    while read line; do
        acc+="$line"$'\n'
        if [ -n "$line" ]; then
            echo -n "$acc"
            acc=""
        fi
    done
}

于 2021-06-22T11:24:08.383 に答える