Öz
Satırları satırsonu olmadan yazdırın, yalnızca yazdırılacak başka satır varsa satırsonu ekleyin.
$ printf 'one\ntwo\n' |
awk '{ printf( "%s%s" , NR>1?"\n":"" , $0 ) }'; echo " done"
one
two done
Diğer çözümler
Bir dosyayla çalışsaydık, sadece bir karakteri ondan kesebiliriz (eğer bir satırsonu ile bitiyorsa):
removeTrailNewline () {[[$ (kuyruk -c 1 "$ 1")]] || || kes -s-1 "$ 1"; }
Bu, dosyadan yalnızca bir karakteri okuması ve ardından truncate
tüm dosyayı okumadan doğrudan ( ) kaldırması gerektiğinden hızlı bir çözümdür .
Ancak, stdin (akış) verileriyle çalışırken, verilerin tümü okunmalıdır. Ve okunduğu anda "tüketilir". Geri iz yok (kesik gibi). Bir akışın sonunu bulmak için akışın sonuna kadar okumamız gerekir. Bu noktada, giriş akışında geri gitmenin bir yolu yoktur, veriler zaten "tüketilmiştir". Bu, biz akışın sonuna kadar ve sonra arabellekteki verilerle bir şeyler yapana kadar verilerin bir çeşit tamponda saklanması gerektiği anlamına gelir .
Çözümlerin en belirgin olanı, akışı bir dosyaya dönüştürmek ve o dosyayı işlemektir. Ancak soru akışın bir tür filtresini istiyor. Ek dosyaların kullanımı ile ilgili değildir.
değişken
Saf çözüm, tüm girdiyi bir değişkene yakalamak olacaktır:
FilterOne(){ filecontents=$(cat; echo "x"); # capture the whole input
filecontents=${filecontents%x}; # Remove the "x" added above.
nl=$'\n'; # use a variable for newline.
printf '%s' "${filecontents%"$nl"}"; # Remove newline (if it exists).
}
printf 'one\ntwo' | FilterOne ; echo 1done
printf 'one\ntwo\n' | FilterOne ; echo 2done
printf 'one\ntwo\n\n' | FilterOne ; echo 3done
hafıza
Sed ile tüm bir dosyayı belleğe yüklemek mümkündür. Sed'de son satırdaki son satırdan kaçınmak mümkün değildir. GNU sed sondaki satırsonu yazdırmaktan kaçınabilir, ancak yalnızca kaynak dosya zaten eksikse. Yani, hayır, basit sed yardım edemez.
-z
Seçeneği ile GNU awk hariç :
sed -z 's/\(.*\)\n$/\1/'
Awk (herhangi bir awk) ile, tüm akışı ve printf
sondaki yeni satır olmadan kaydırın.
awk ' { content = content $0 RS }
END { gsub( "\n$", "", content ); printf( "%s", content ) }
'
Bir dosyanın tamamını belleğe yüklemek iyi bir fikir olmayabilir, çok fazla bellek tüketebilir.
Bellekte iki satır
Awk olarak, önceki satırı bir değişkende saklayıp mevcut olanı yazdırarak döngü başına iki satır işleyebiliriz:
awk 'NR>1{print previous} {previous=$0} END {printf("%s",$0)}'
Doğrudan işleme
Ama daha iyisini yapabiliriz.
Biz bir satır olmadan mevcut çizgisini yazdırmak ve bir sonraki çizgi var olan tek bir yeni satır yazdırmak, biz bir zaman ve gelecek son satırında bir satır işlemek değil bir eğik yeni satır vardır:
awk 'NR == 1 {printf ("% s", $ 0); sonraki}; {printf ("\ n% s", $ 0)} '
Veya başka bir şekilde yazılmış:
awk 'NR>1{ print "" }; { printf( "%s", $0 ) }'
Veya:
awk '{ printf( "%s%s" , NR>1?"\n":"" , $0 ) }'
Yani:
$ printf 'one\ntwo\n' | awk '{ printf( "%s%s" , NR>1?"\n":"" , $0 ) }'; echo " done"
one
two done
chomp
olarak,chomp
sadece en çok bir arka yeni satır ile siler.