ลบบรรทัดว่างโดยใช้ sed


351

ฉันพยายามลบบรรทัดว่างโดยใช้ sed:

sed '/^$/d'

แต่ฉันไม่มีโชคกับมัน

ตัวอย่างเช่นฉันมีเส้นเหล่านี้:

xxxxxx


yyyyyy


zzzzzz

และฉันต้องการให้เป็นเช่น:

xxxxxx
yyyyyy
zzzzzz

สิ่งที่ควรเป็นรหัสสำหรับสิ่งนี้?


2
sed คำสั่งรูปลักษณ์ที่ดีของคุณก็ควรจะทำงาน
perreal

คำสั่งดังกล่าวจะไม่ทำงานแม้ว่าคุณจะไม่มีช่องว่าง / แท็บ แต่จะจบด้วยบรรทัด CR + LF
devnull

คำตอบ:


628

คุณอาจมีช่องว่างหรือแท็บในบรรทัด "ว่าง" ของคุณ ใช้คลาส POSIXด้วยsedเพื่อลบบรรทัดทั้งหมดที่มีช่องว่างเท่านั้น:

sed '/^[[:space:]]*$/d'

เวอร์ชันที่สั้นกว่าที่ใช้ ERE ตัวอย่างเช่นกับ gnu sed:

sed -r '/^\s*$/d'

(โปรดทราบว่า sed ไม่รองรับ PCRE)


3
@HuStmpHrrr gnu sed ไม่รองรับ PCRE เลย มันเป็น ERE ด้วย-r
Kent

8
OS X ต้องการsed -i "" '/^[[:space:]]*$/d' <filename>,
jww

@BernieReiter ^\s*$จะจับคู่บรรทัดทั้งหมด "empty" ว่างเปล่าที่นี่หมายถึงบรรทัดไม่มีตัวอักษรหรือบรรทัดประกอบด้วยสตริงว่างเท่านั้น (เช่นช่องว่าง) บรรทัดที่ตรงกันทั้งหมดจะถูกลบออกโดย sed พร้อมกับdคำสั่ง
Kent

97

ฉันไม่มีawkวิธีแก้ไข:

awk 'NF' file

ซึ่งจะกลับมา:

xxxxxx
yyyyyy
zzzzzz

มันทำงานอย่างไร เนื่องจากNFหมายถึง "จำนวนฟิลด์" บรรทัดเหล่านั้นว่างเปล่ามี 0 fiedls ดังนั้น awk จะประเมินค่า 0 เป็น False และไม่มีการพิมพ์บรรทัด อย่างไรก็ตามหากมีอย่างน้อยหนึ่งฟิลด์การประเมินค่าเป็น True และawkดำเนินการตามค่าเริ่มต้น: พิมพ์บรรทัดปัจจุบัน


1
whoah ยังทำงานอยู่กับรุ่น "ย่อเล็กสุด" ของ BSD ของ awk (รุ่น 20121220 (FreeBSD) ขอบคุณ :-)
Bernie Reiter

@BernieReiter คุณยินดีต้อนรับ :) ใช่นี่เป็นสิ่งที่สำนวนพื้นฐานมากทุกรุ่น awk อนุญาต
fedorqui 'ดังนั้นหยุดการทำร้าย'

และมันก็เร็วกว่ามาก - สำหรับการทดสอบที่รวดเร็วและสกปรก - ฉันเรียก awk สองครั้ง: $ time (topic companies <data.tpx | awk 'NF' - | awk -f dialog_menu.awk -) real 0m0.006s user 0m0.000s sys 0m0.008s $ time (topic companies <data.tpx | gsed '/^\s*$/d' | awk -f dialog_menu.awk -) real 0m0.014s user 0m0.002s sys 0m0.006s คุณจะรู้วิธีที่ดีที่จะรวมสิ่งนี้ไว้ในสคริปต์ awk-like เช่นรูปแบบหรือไม่? awk '/ mypattern / {do stuff ... }'
เบอร์นีไรเตอร์

@BernieReiter คุณสามารถพูดawk 'NF {do stuff...}'ได้
fedorqui 'ดังนั้นหยุดทำอันตราย'

1
โปรดทราบว่าการดำเนินการนี้จะละเว้นบรรทัดที่มีช่องว่างเท่านั้น
wisbucky

60

sed '/^$/d'ควรจะดีคุณคาดหวังว่าจะแก้ไขไฟล์ในสถานที่? ถ้าเป็นเช่นนั้นคุณควรใช้-iธง

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


ใช่. ฉันกำลังแก้ไขไฟล์ * .csv จะวาง -i ไว้ในคำสั่ง sed ได้อย่างไร?
โจนัส

2
sed -i '/^$/d'เป็นวิธีหนึ่งในการทำมัน
Alberto Zaccagni

49

1
เหล่านี้ปรากฏขึ้นอย่างถูกต้องในเครื่องมือออนไลน์ของคุณ แต่[]ควรไม่หนีในการแสดงออกวงเล็บดังนั้นรหัสที่นี่ไม่ได้ที่ถูกต้องสำหรับ\[\[:space:\]\]หรือ\[ \t\]- ควรจะเป็นและ[[:space:]] [ \t]
Benjamin W.

1
@BenjaminW ขอบคุณสำหรับการจับที่ สิ่งเหล่านี้ไม่ได้มาจากผู้เขียนต้นฉบับ แต่มาจากการแก้ไข 3เมื่อเปลี่ยนจากข้อความปกติเป็น "รหัส" ซึ่งจากนั้น "เปิดเผย" การหลบหนี `` ` ตอนนี้ฉันซ่อมมันแล้ว
wisbucky

30

ฉันเชื่อว่านี่เป็นวิธีที่ง่ายที่สุดและเร็วที่สุด:

cat file.txt | grep .

หากคุณต้องการละเว้นบรรทัดสีขาวทั้งหมดด้วยให้ลองทำดังนี้:

cat file.txt | grep '\S'

ตัวอย่าง:

s="\
\
a\
 b\
\
Below is TAB:\
    \
Below is space:\
 \
c\
\
"; echo "$s" | grep . | wc -l; echo "$s" | grep '\S' | wc -l

เอาท์พุท

7
5

5
ไม่จำเป็นต้องใช้cat, grepใช้เวลาไฟล์เช่นกัน:grep . file.txt
Ciro Santilli郝海东冠状病六四事件法轮功

3
ใช่ฉันรู้ แต่คำถามเริ่มต้นไม่ได้กล่าวถึงว่าแหล่งที่มาเป็นไฟล์หรืออย่างอื่นดังนั้นการแก้ปัญหาคือสิ่งที่เกิดขึ้นหลังจาก "|" และก่อนหน้านี้เป็นเพียงตัวอย่างของแหล่งที่มา เพียงเพื่อแยกความแตกต่างโซลูชันจากแหล่งที่มาของเส้น
Vadim

2
grep '\S'ไม่พกพาอย่างแน่นอน หากคุณมีgrep -Pแล้วคุณสามารถใช้grep -P '\S'แต่ไม่รองรับในทุกแพลตฟอร์ม
tripleee

ข้อเสียของการgrep .เปรียบเทียบกับโซลูชั่นอื่น ๆ คือมันจะเน้นข้อความทั้งหมดในสีแดง โซลูชันอื่น ๆ สามารถคงสีเดิมไว้ได้ เปรียบเทียบunbuffer apt search foo | grep .กับunbuffer apt search foo | grep -v ^$
wisbucky

15

ด้วยความช่วยเหลือจากคำตอบที่ยอมรับได้ที่นี่และคำตอบที่ได้รับการยอมรับฉันใช้:

$ sed 's/^ *//; s/ *$//; /^$/d; /^\s*$/d' file.txt > output.txt

`s/^ *//`  => left trim
`s/ *$//`  => right trim
`/^$/d`    => remove empty line
`/^\s*$/d` => delete lines which may contain white space

นี้ครอบคลุมทุกฐานและทำงานได้อย่างสมบูรณ์แบบสำหรับความต้องการของฉัน ความรุ่งโรจน์ของผู้โพสต์ดั้งเดิม @Kent และ @kev


5

คุณสามารถพูดได้:

sed -n '/ / p' filename    #there is a space between '//'

.. ซึ่งหมายถึงprint all lines except the empty one(s)และเงียบสงบ
ติโม

3

อีกตัวเลือกหนึ่งโดยไม่ต้องsed, awk, perlฯลฯ

strings $file > $output

strings - พิมพ์สตริงของตัวอักษรที่พิมพ์ได้ในไฟล์


คุณหมายถึงstringsแทนstring?
Mickael B.



2

คุณมักจะเห็นพฤติกรรมที่ไม่คาดคิดเพราะไฟล์ข้อความของคุณถูกสร้างขึ้นบน Windows \r\nดังนั้นในตอนท้ายของลำดับสาย คุณสามารถใช้ dos2unix เพื่อแปลงเป็นไฟล์ข้อความสไตล์ UNIX ก่อนเรียกใช้ sed หรือใช้

sed -r "/^\r?$/d"

เพื่อลบบรรทัดว่างไม่ว่าจะมีการขึ้นบรรทัดใหม่หรือไม่


สวัสดีสิ่งที่-rธงทำและเป็นไปได้ที่จะรวมกับ-iการแก้ไขไฟล์โดยตรงและหลีกเลี่ยงการพิมพ์ไปที่หน้าจอ นอกจากนี้ฉันคิดว่าคำสั่งนี้จะทำงานเป็นsed -r "/^\r$/d"
อเล็กซานเด Cska

0

bashคำตอบเฉพาะของฉันคือการแนะนำให้ใช้perlตัวดำเนินการทดแทนพร้อมกับgแฟล็กรูปแบบโกลบอลสำหรับสิ่งนี้ดังนี้:

$ perl -pe s'/^\n|^[\ ]*\n//g' $file
xxxxxx
yyyyyy
zzzzzz

คำตอบนี้แสดงให้เห็นถึงการบัญชีว่าบรรทัดว่างมีช่องว่างในนั้นหรือไม่[\ ]*รวมทั้งใช้|เพื่อแยกคำค้นหา / หลายฟิลด์ ทดสอบบน macOS High Sierra และ CentOS 6/7

FYI, รหัสดั้งเดิมของ OP sed '/^$/d' $fileทำงานได้ดีในbashTerminal บน macOS High Sierra และ CentOS 6/7 Linux ที่คลัสเตอร์ซูเปอร์คอมพิวเตอร์ประสิทธิภาพสูง


-3

สำหรับฉันด้วย FreeBSD 10.1 ที่มีsed ใช้งานได้เฉพาะโซลูชันนี้:

sed -e '/^[     ]*$/d' "testfile"

ภายใน[]มีสัญลักษณ์ช่องว่างและแท็บ

ไฟล์ทดสอบประกอบด้วย:

fffffff next 1 tabline ffffffffffff

ffffffff next 1 Space line ffffffffffff

ffffffff empty 1 lines ffffffffffff

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