ลบอักขระสิ้นสุดบรรทัดออกจาก stdout หรือไม่ หลายบรรทัดเป็นบรรทัดเดียว


14

ฉันมีสคริปต์ที่แสดงผลข้อความต่อไปนี้ นี่คือผลลัพธ์จากโมเด็มNetSL 2210-02 ADSL2

ADSL Line State:        Up
ADSL Startup Attempts:  1
ADSL Modulation:        DMT
ADSL Data Path:         Fast
Datapump Version:       DSP 7.2.3.0, HAL 7.2.1.0
SNR Margin:                   8.20        9.00 dB
Line Attenuation:            57.50       31.00 dB
Output Power:                17.09       12.34 dBm
Errored Seconds:                 0           0
Loss of Signal:                  0         476
Loss of Frame:                   0           0
CRC Errors:                  57921         416
Data Rate:                    2880        1024

ฉันจะลบอักขระสิ้นสุดบรรทัดสำหรับแต่ละบรรทัดได้อย่างไร ฉันต้องการให้ผลลัพธ์ออกมาเป็นแบบนี้ (ใช่มันน่าเกลียด):

ADSL Line State:        Up ADSL Startup Attempts:  1 ADSL Modulation:        DMT ADSL Data Path:         Fast Datapump Version:       DSP 7.2.3.0, HAL 7.2.1.0 SNR Margin:                   8.20        9.00 dB Line Attenuation:            57.50       31.00 dB Output Power:                17.09       12.34 dBm Errored Seconds:                 0           0 Loss of Signal:                  0         476 Loss of Frame:                   0           0 CRC Errors:                  57921         416 Data Rate:                    2880        1024 

ฉันลองวิธีแก้ปัญหาเช่นนี้ แต่พวกเขาไม่ทำงาน:

# (This simply outputs the contents of the script, unmodified)
stefanl@hosta:~/Work/Cacti $ ./script | sed -e 's/$//'

ฉันก็ลองใช้trดู ฉันคาดหวังว่าคำสั่งต่อไปนี้เพื่อแทนที่อักขระขึ้นบรรทัดใหม่ด้วยอักขระช่องว่าง สิ่งนี้จะนำหลายบรรทัดมารวมกันเป็นหนึ่งบรรทัดยาวเดียว แต่จะแสดงเฉพาะบรรทัดสุดท้ายของเอาต์พุต ดูเหมือนว่าจะเขียนทับแต่ละบรรทัดถัดไปด้วยบรรทัดถัดไปของเอาต์พุต

stefanl@hosta:~/Work/Cacti $ ./script | tr '\n' ' '
Data Rate:                    2880        1024stefanl@hosta:~/Work/Cacti $
stefanl@hosta:~/Work/Cacti $

อัปเดต :

เมื่อตรวจสอบเพิ่มเติมดูเหมือนว่าแต่ละบรรทัดจะถูกนำหน้าด้วยอักขระที่ส่งคืน การแสดงนี้ขึ้นเป็นเมื่อใช้^M lessดังนั้นฉันจึงเพิ่มสองtrคำสั่ง หนึ่งตัวเพื่อลบอักขระบรรทัดใหม่หนึ่งตัวเพื่อลบอักขระย้อนกลับ

./script | | tr -d '\n' | tr -d '\r'

คำตอบ:


18

sedจะไม่ทำงาน (ง่าย) เพราะทำงานบนบรรทัดทีละครั้ง คุณสามารถทำได้ แต่มันจะเกี่ยวข้องกับการคัดลอกอินพุตทั้งหมดลงในบัฟเฟอร์พัก

trจริง ๆ แล้วควรทำงานตามที่คุณวางไว้ คุณแน่ใจหรือไม่ว่าบรรทัดใหม่เป็น\ns คุณสามารถทำให้มันง่ายขึ้นเล็กน้อยโดยการลบบรรทัดใหม่แทนที่จะแปลงเป็นช่องว่าง:

tr -d '\n'

ทั้งสองtr '\n' ' 'และtr -d '\n' จะพันสายด้วยวิธีแปลก ๆ ฉันอัปเดตคำถามเพื่อแสดงผลลัพธ์ ดังนั้นฉันอาจต้องใช้trแต่ฉันต้องหาวิธีใช้ให้ถูกต้อง
Stefan Lasiewski

คุณช่วยขยายความว่าอะไรเกี่ยวกับมันแปลก ๆ ? สาเหตุที่พรอมต์ของคุณสิ้นสุดที่บรรทัดเดียวกันกับบรรทัดสุดท้ายของเอาต์พุตเนื่องจากคุณลบ '\ n' ที่ท้ายบรรทัด หากคุณอธิบายผลลัพธ์สุดท้ายที่คุณต้องการฉันมั่นใจว่าจะมีบางคนที่มาพร้อมตัวกรองที่เหมาะสม
Steven D

ตกลงฉันคิดว่าฉันจะชัดเจนมากขึ้น ฉันหวังว่าจะรวมหลายบรรทัดเหล่านี้ไว้ในบรรทัดเดียว ฉันคาดว่าtr '\n' ' 'จะลบอักขระบรรทัดใหม่และแทนที่ด้วยอักขระเว้นวรรคและดังนั้นจึงมีหนึ่งบรรทัดยาว
Stefan Lasiewski

@ สตีเว่น: ฉันอัปเดตคำถามของฉันเพื่อหารือเกี่ยวกับสิ่งที่ฉันคาดหวังที่จะเห็นและสิ่งที่พิมพ์จริงบนหน้าจอ
Stefan Lasiewski

อืมมม เว้นแต่ว่าผลลัพธ์ของคุณจะไม่จบลงด้วย \ n สิ่งนี้ควรให้ผลลัพธ์ที่คุณคาดหวัง คุณลอง piping เป็นไฟล์แล้วยืนยันว่าการตัดบรรทัดไม่ใช่สิ่งที่คำศัพท์ของคุณทำเพื่อคุณใช่ไหม
Steven D

5

นอกจากtrนี้ยังมีวิธีอื่นที่คุณสามารถใช้ได้

awk

awk '1' ORS= file

เปลือก

while read -r line; do printf "%s " "$line"; done <file

sed

sed -e ':a' -e 'N;s/\n/ /;ba' file

0

ใช้tr -s '\n'เพื่อแทนที่ลำดับของอักขระขึ้นบรรทัดใหม่ที่เกิดซ้ำด้วยการขึ้นบรรทัดเดียวใหม่

ตัวอย่าง:

>>> echo -e "Squeeze\n\n\nthose\n\n\n\nnewlines\n"
Squeeze


those



newlines

2z [franck:~] $ 
>>> echo -e "Squeeze\n\n\nthose\n\n\n\nnewlines\n" | tr -s '\n'
Squeeze
those
newlines

(ดูman tr)


0

หากต้องการลบอักขระบรรทัดใหม่ให้tr -d '\n' < fileใช้ paste -sd '\0' fileแต่จะเข้าร่วมทุกสายที่ของ

tr -d '\n' สร้างเอาต์พุตที่ไม่ใช่ข้อความเนื่องจากไม่ได้ยกเลิกหนึ่งบรรทัดด้วยอักขระขึ้นบรรทัดใหม่

ในการลบอักขระ CR ทั้งหมดคุณสามารถทำได้:

tr -d '\r' < file | paste -sd '\0' -

หากต้องการลบเฉพาะอักขระ CR ที่อยู่ท้ายบรรทัด:

CR=$(printf '\r')
sed "s/$CR\$//" < file | paste -sd '\0' -

หรือใช้awkสำหรับทุกสิ่ง:

awk '{gsub(/\r$/, ""); printf "%s", $0} 
     END {if (NR) print ""}' < file

หรือใช้dos2unix(ซึ่งจะลบ CR ที่ต่อท้ายเหล่านั้นและแก้ไขปัญหาอื่น ๆ ด้วยไฟล์ข้อความจาก Microsoft OSes):

 dos2unix < file | paste -sd '\0' -
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.