Bash: Çıktıdan sonraki şerit çizgisini ayırma


189

Bash (veya belirli olmak gerekirse wc -l < log.txt) komutları yürüttüğümde , çıktıdan sonra satır sonu içeriyor. Ondan nasıl kurtulurum?

Yanıtlar:


251

Beklenen çıktınız tek bir satırsa , tüm yeni satır karakterlerini çıktıdan kaldırabilirsiniz. 'Tr' yardımcı programına veya tercih edilirse Perl'e yöneltilmesi nadir değildir:

wc -l < log.txt | tr -d '\n'

wc -l < log.txt | perl -pe 'chomp'

Sondaki yeni satırı kaldırmak için komut değiştirme özelliğini de kullanabilirsiniz:

echo -n "$(wc -l < log.txt)"

printf "%s" "$(wc -l < log.txt)"

Lütfen OP'nin kabul edilen cevabı seçme kararına katılmadığımı unutmayın. Mümkün olan yerlerde 'xargs' kullanmaktan kaçınmak gerektiğine inanıyorum. Evet, havalı bir oyuncak. Hayır, burada ihtiyacınız yok.


Beklediğiniz çıktıda birden fazla satır varsa, başka bir karar vermeniz gerekir:

MULTIPLE satırsonu karakterlerini dosyanın sonundan kaldırmak istiyorsanız, yine cmd yerine kullanın:

printf "%s" "$(< log.txt)"

SON satırsonu karakterini bir dosyadan kesinlikle kaldırmak istiyorsanız Perl kullanın:

perl -pe 'chomp if eof' log.txt


Kaldırmak istediğiniz bir satırsonu karakteriniz olduğundan eminseniz, son bayt dışındaki her şeyi seçmek için GNU coreutils'den 'head' kullanabilirsiniz. Bu oldukça hızlı olmalı:

head -c -1 log.txt

Ayrıca, eksiksizlik için, 'cat' ve 'tümünü göster' bayrağını kullanarak yeni satırınızın (veya diğer özel) karakterlerin dosyanızda hızlı bir şekilde kontrol edebilirsiniz. Dolar işareti karakteri her satırın sonunu gösterir:

cat -A log.txt

Bu, başlıktaki TÜM yeni satırları çıkarır, yalnızca başlığın istediği yeni satır sonunu değil.
Cody A. Ray

@ CodyA.Ray: Sorunun sadece tek bir çıktı satırı üretecek belirli bir komutu açıkladığını kabul etmelisiniz. Ancak cevabımı daha genel duruma uyacak şekilde güncelledim. HTH.
Steve

3
Kısa seçeneklerin uzun seçeneklerle değiştirilmesi durumunda bu daha iyi olur. Uzun seçenekler yanı sıra işlevi öğretir tr --delete '\n'.
Elijah Lynn

1
Ben de yaptım| tr -d '\r'
AlikElzin-kilaka

Dosya çok büyükse cmd ikame çözümünün uzun bir çizgiye yol açabileceğini belirtmek gerekir.
phk

88

Tek yön:

wc -l < log.txt | xargs echo -n

24
Daha iyi:echo -n `wc -l log.txt`
Satya

9
Geri dönüşlerde komut yürütme neden pipo kullanmaktan daha iyidir?
Matthew Schinckel

2
Bunlar sadece sondaki yeni satırları kaldırmakla kalmaz, aynı zamanda ardışık boşlukları (daha kesin olarak tanımlandığı gibi IFS) bir boşluğa sıkıştırır . Örnek echo "a b" | xargs echo -n:; echo -n $(echo "a b"). Bu, kullanım durumu için bir sorun olabilir veya olmayabilir.
musiphil

14
Daha da kötüsü, çıktı ile başlarsa -e, seçenek olarak yorumlanacaktır echo. Kullanımı her zaman daha güvenlidir printf '%s'.
musiphil

1
xargssistemimde çok yavaş (ve diğer sistemlerde de olduğundan şüpheleniyorum), bu yüzden printf '%s' $(wc -l log.txt)daha hızlı olabilir, çünkü printfgenellikle yerleşiktir (Ayrıca bilgi yönlendirmesi olmadığı için). Asla backtick kullanmayın, yeni POSIX sürümlerinde kullanımdan kaldırıldı ve birçok dezavantajı var.
yyny

14

Bash değişken ikamesinde beyaz boşlukların çıkarılması için doğrudan destek de vardır :

testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}

1
Ayrıca kullanabilirsiniztrailing_linebreak_removed=${testvar%?}
PairedPrototype

Komut ikamesi kullanıyorsanız, sondaki yeni satırları kaldırmak için herhangi bir şey yapmanız gerekmediğini unutmayın. Bash bunu komut değiştirme işleminin bir
Michael Burr

10

Çıktısını bir değişkene atarsanız, bashboşlukları otomatik olarak şeritler:

linecount=`wc -l < log.txt`

10
Kesin yeni satırlar kesin olarak çıkarılır. Değişken atamasını değil, onları kaldıran komut ikamesidir.
chepner

2
Cygwin bash'da $ (cmd / c echo% VAR%) kullanırken sondaki boşluk kaldırılmadığını gördüm. Bu durumda $ {var %% [[: space:]]} kullanmak zorunda kaldım.
Andrey Taranov

1
Not: değişken ataması değil, satırsonlarını kaldıran ifade genişletmesidir.
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

10

printf sizin için sondaki yeni satırı zaten keser:

$ printf '%s' $(wc -l < log.txt)

Detay:

  • printf, içeriğinizi %sdize yer tutucu yerine yazdırır .
  • Bir satırsonu ( %s\n) yazdırmasını söylemezseniz , olmaz.

7
Komutun etrafına çift tırnak işareti koyarsanız "$(command)", dahili yeni satırlar korunur ve yalnızca sondaki yeni satır kaldırılır. Kabuk burada tüm işleri yapıyor - printfsadece komut değiştirme sonuçlarını tekrar yönlendirmenin bir yoludur stdout.
Brent Bradburn

2
Buradaki yeni çizgiyi sıyrıran printf değil, $( )yapı ile yapan kabuk . İşte kanıt:printf "%s" "$(perl -e 'print "\n"')"
Flimm

Yine, ortaya çıkan komut satırının çok uzun olabileceğini belirtmek gerekir.
phk

Bu, @ nobar'ın önerisi ile uygun bir çözümdür:$ printf '%s' "$(wc -l < log.txt)"
Ilias Karim

10

Yalnızca son satırsonu kaldırmak istiyorsanız , aşağıdakileri yapın:

sed -z '$ s/\n$//'

sedBir eklemez \0sınırlayıcı olarak ayarlanırsa o zaman akışının sonuna kadar NULüzeri -zbir POSIX metin dosyası oluşturmak için ise (a içinde amaçla belirlenen \nbir nihai daima çıkış, olacaktır) \nolmadan -z.

Örneğin:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender

Ve hiçbir kanıt kanıtlamak için NUL:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72                        foo.bar

Birden fazla sondaki yeni satırı kaldırmak için aşağıdakileri yapın :

sed -Ez '$ s/\n+$//'

Sanırım bu bir GNU uzantısı, Mac sedsağlamıyor -z.
Spidey

7

Bash'te herhangi bir şeyin çıktısını satır sonu olmadan yazdırmak istiyorsanız, -nanahtarla yankılanırsınız .

Eğer zaten bir değişkene sahipseniz, sondaki yeni satır kırpılmış olarak yankılanır :

    $ testvar=$(wc -l < log.txt)
    $ echo -n $testvar

Veya bunun yerine tek bir satırda yapabilirsiniz:

    $ echo -n $(wc -l < log.txt)

2
Değişken teknik olarak gereksizdir. echo -n $(wc -l < log.txt)aynı etkiye sahiptir.
chepner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.