ฉันมีเอกสารที่มีบรรทัดว่างเปล่าจำนวนมาก
ฉันจะลบออกได้อย่างไรเมื่อมี 2 หรือมากกว่ารวมกัน
ฉันลองsed "s/\n\n//"
ไฟล์แล้วแต่ใช้งานไม่ได้ ไม่มีข้อผิดพลาด
ฉันมีเอกสารที่มีบรรทัดว่างเปล่าจำนวนมาก
ฉันจะลบออกได้อย่างไรเมื่อมี 2 หรือมากกว่ารวมกัน
ฉันลองsed "s/\n\n//"
ไฟล์แล้วแต่ใช้งานไม่ได้ ไม่มีข้อผิดพลาด
คำตอบ:
เพียงเพื่อลบบรรทัดว่าง:
sed '/^$/d'
sed
เป็นเส้นที่มุ่งเน้นดังนั้นการคิดในแง่ของ "2 หรือมากกว่าของไบต์ที่เฉพาะเจาะจง" ทำงานยกเว้นเมื่อไบต์นั้นเป็นบรรทัดใหม่ ถ้าอย่างนั้นคุณต้องคิดถึงบางสิ่งที่ใช้ได้กับทั้งสาย
sed
สามารถจัดการหลายบรรทัดผ่านคุณสมบัติ "pattern space" / "hold space" แต่ฉันรู้สึกว่ามันซับซ้อนเกินไป ;-)
1!
(ตรงกับทุกคนยกเว้นบรรทัดที่ 1) sed '1!{/^$/d'}
ดังนี้:
sed
เท่านั้น การสร้างไฟล์เป็นหลักจะลบไฟล์ที่มีอยู่ด้วยชื่อเดียวกัน sed '/^&/d' file.txt > otherfile.txt
จะทำงาน.
sed
ไม่จำเป็นต้อง grep
จะทำ:
grep .
(นั่นคือgrep
SPC จุดที่ตรงกับบรรทัดใด ๆ ที่มีอักขระอย่างน้อยหนึ่งตัว)
นอกจากนี้ยังมี:
tr -s '\n'
(บีบลำดับอักขระขึ้นบรรทัดใหม่ใด ๆ เป็นหนึ่ง)
ตามที่ระบุไว้โดย Chris ทั้งคู่จะไม่เทียบเท่ากันเนื่องจากการลบบรรทัดว่าง (เช่นคำตอบแรกด้านบนและคำตอบอื่น ๆ ส่วนใหญ่มุ่งเน้นที่นี่) ไม่เหมือนกับการบีบลำดับของอักขระขึ้นบรรทัดใหม่ตามที่ร้องขอในกรณีที่บรรทัดแรกว่างเปล่า ใช้เวลาเพียงหนึ่งอักขระ newline นำไปสู่การทำให้บรรทัดแรกที่ว่างเปล่า
การได้เห็น @Bruce Ediger คำตอบ sed
ไม่ใช่เครื่องมือที่ดีที่สุดสำหรับสิ่งนั้นเนื่องจากเป็นบรรทัดตามและถือว่า\n
เป็นอักขระที่สิ้นสุดของบรรทัดซึ่งมีความซับซ้อนsed
อาจเป็นเครื่องมือที่สมบูรณ์แบบสำหรับงาน แต่ก็มีตัวเลือกอื่น ๆ :
Perl
perl -ne 'print if /./' file.txt
หรือ
perl -pe '$/=""; s/\n+/\n/;' file.txt
ขอบคุณ@ruakhที่ทำให้ฉันไปและอ่านสิ่งนี้ :
$ /
ตัวคั่นเรคคอร์ดอินพุตบรรทัดใหม่เป็นค่าเริ่มต้น สิ่งนี้มีอิทธิพลต่อความคิดของ Perl ว่า "บรรทัด" คืออะไร ทำงานเหมือนตัวแปร RS ของ awk รวมถึงการปฏิบัติกับบรรทัดว่างเป็นเทอร์มิเนเตอร์หากตั้งค่าเป็นสตริงว่าง (บรรทัดว่างไม่สามารถมีช่องว่างหรือแท็บใด ๆ ) คุณสามารถตั้งให้มันเป็นสตริงที่มีหลายตัวละครเพื่อให้ตรงกับจุดสิ้นสุดของตัวละครหลายตัวหรือเพื่อยกเลิกการอ่านจนจบไฟล์ การตั้งค่าเป็น "\ n \ n" หมายถึงบางสิ่งที่แตกต่างจากการตั้งค่าเป็น "" เล็กน้อยหากไฟล์มีบรรทัดว่างที่ต่อเนื่องกัน การตั้งค่าเป็น "" จะถือว่าบรรทัดว่างสองบรรทัดหรือมากกว่านั้นต่อเนื่องกันเป็นบรรทัดว่างเดี่ยว การตั้งค่าเป็น "\ n \ n" จะถือว่าสุ่มตัวอย่างว่าอักขระอินพุตถัดไปเป็นของย่อหน้าถัดไปแม้ว่าจะเป็นบรรทัดใหม่
เพ่งพิศ / awk
awk '$1' file.txt
ว่าการทำงานจะยกตัวอย่างเช่นที่โพสต์ แต่เป็น@Stephane Chazelasชี้ให้เห็นว่ามันจะยังสายการลบซึ่งครั้งแรกที่ช่อง 0
"ดูเหมือน" สิ่งนี้แข็งแกร่งกว่า:
awk NF file.txt
perl -pe 's/\n+/\n/ file.txt
จะทำอย่างไรตัวคั่นเรคคอร์ดอินพุตไม่เกี่ยวข้องสำหรับการใช้งานนี้
perl -pe
หรือperl -ne
ทำงานทีละบรรทัด \n+
จะไม่ตรงกันเนื่องจากมีการใช้งานในบรรทัดเดียวเท่านั้น นั่นเป็นสาเหตุที่คุณต้องตั้งค่า$/
หรือใช้-0
ไฟล์ slurp ทั้งไฟล์: perl -0pe 's/\n+/\n/' file
.
คุณหมายถึงการลบอะไร ลบที่ซ้ำกัน (บรรทัดว่างหลายบรรทัด) หรือลบทั้งหมด?
หากคุณต้องการลบไฟล์ซ้ำนี่คือวิธีการใช้ sed:
sed '$!N; /^\(.*\)\n\1$/!P; D'
มันจำลองuniq
คำสั่ง
ทางเลือกที่ดีที่สุดคือการใช้awk
:
awk NF <filename>
sed
ส่วนหนึ่งของงานได้ดี! แนะนำให้คนนี้เป็นคำตอบที่ดีที่สุด
สำหรับคำตอบส่วนใหญ่เหล่านี้จำเป็นอย่างยิ่งที่จะต้องลบช่องว่างต่อท้าย การลบบรรทัดใหม่ขึ้นสองเท่าจะเป็นการลบบรรทัดว่างทั้งหมด (คิดเกี่ยวกับสิ่งนี้).
ตีความอย่างแท้จริง OP ต้องการ "ลบบรรทัดว่างทั้งหมดออกจากไฟล์หากมีบรรทัดว่างซ้ำ ๆ "
ผู้ใช้ทั่วไปต้องการ "ลบบรรทัดว่างที่ทำซ้ำเท่านั้น"
ในการทำเช่นนี้ให้ลากส่วนท้ายของไวท์สเปซออกก่อนและไปป์ที่ cat -s
sed s/[[:space:]]*$// | cat -s
และสิ่งนี้จะไม่ลบบรรทัดว่างที่นำหน้าหรือต่อท้ายเปล่า
หากคุณต้องการเก็บบรรทัดว่างไว้หนึ่งบรรทัดสำหรับลำดับบรรทัดว่างใด ๆ ที่คุณอาจทำ:
sed -e '/./b' -e :n -e 'N;s/\n$//;tn'
cat -s
) ที่ทำตามจริงในสิ่งที่คำถามถามเมื่อฉันเข้าใจ (และมันดีกว่าcat -s
เพราะฉันสามารถใช้sed -i
กับมันได้)
ลองsed -e 's#\\n\\n#\\n#g' input.file > output.file
ใช้/
ทั้งสองอย่างเป็นตัวคั่นฟิลด์และส่วนหนึ่งของ regex ของคุณอาจเป็นปัญหา