を使用して、重複した空行を削除してテキスト ドキュメントを圧縮しようとしていますsed
。これは私がやっていることです(役に立たない):
sed -i -E 's/\n{3,}/\n/g' file.txt
このマニュアルによると、正しくないことは理解していますが、正しく行う方法がわかりません。ありがとう。
トリプリーが上で示唆したように、私は代わりにPerlを使用していsed
ます:
perl -0777pi -e 's/\n{3,}/\n\n/g'
あなたの例では の複数の\n
実行\n
を\n\n
. それを念頭に置いて、ここに2つの解決策があります:
sed '/^$/{ :l
N; s/^\n$//; t l
p; d; }' input
sed の多くの実装では、埋め込まれた改行を;
.
awk 't || !/^$/; { t = !/^$/ }'
翻訳機能を使う
tr -s '\n'
-s または --squeeze-repeats は、繰り返される文字のシーケンスを 1 つのインスタンスに減らします。
tr -s '\n'
これはまたはcat -s
で処理する方がはるかに優れていますが、 に固執する場合sed
は、GNU sed マニュアルのセクション 4.17 の例を次に示します。
#!/usr/bin/sed -f
# on empty lines, join with next
# Note there is a star in the regexp
:x
/^\n*$/ {
N
bx
}
# now, squeeze all '\n', this can be also done by:
# s/^\(\n\)*/\1/
s/\n*/\
/
OPは空の行を圧縮したいと思います。たとえば、9つの連続した空の行がある場合、彼は3つだけにしたいと考えています。まさにそれを行う小さなbashスクリプトを作成しました:
#! /bin/bash
TOTALLINES="$(cat file.txt|wc -l)"
CURRENTLINE=1
while [ $CURRENTLINE -le $TOTALLINES ]
do
L1=$CURRENTLINE
L2=$(($L1 + 1))
L3=$(($L1 +2))
if [[ $(cat file.txt|head -$L1|tail +$L1) == "" ]]||[[ $(cat file.txt|head -$L1|tail +$L1) == " " ]]
then
L1EMPTY=true
else
L1EMPTY=false
fi
if [[ $(cat file.txt|head -$L2|tail +$L2) == "" ]]||[[ $(cat file.txt|head -$L2|tail +$L2) == " " ]]
then
L2EMPTY=true
else
L2EMPTY=false
fi
if [[ $(cat file.txt|head -$L3|tail +$L3) == "" ]]||[[ $(cat file.txt|head -$L3|tail +$L3) == " " ]]
then
L3EMPTY=true
else
L3EMPTY=false
fi
if [ $L1EMPTY = true ]&&[ $L2EMPTY = true ]&&[ $L3EMPTY = true ]
then
#do not cat line to temp file
echo "Skipping line "$CURRENTLINE
else
echo "$(cat file.txt|head -$CURRENTLINE|tail +$CURRENTLINE)">>temp.txt
echo "Writing line " $CURRENTLINE
fi
((CURRENTLINE++))
done
cat temp.txt>file.txt
rm -r temp.txt
FINALTOTALLINES="$(cat file.txt|wc -l)"
EMPTYLINELINT=$(( $CURRENTLINE - $FINALTOTALLINES ))
echo "Deleted " $EMPTYLINELINT " empty lines."