ฉันจะลบอักขระบรรทัดใหม่ที่ท้ายไฟล์ได้อย่างไร


33

ให้ฉันชัดเจนเกี่ยวกับอักขระขึ้นบรรทัดใหม่:

$ echo Hello > file1 ; cat file1
Hello
$ echo -n  Hello > file2 ; cat file2
Hello$ 

ที่นี่คุณจะเห็นว่าfile1มีอักขระขึ้นบรรทัดใหม่ในตอนท้ายขณะที่file2ยังไม่มี

ตอนนี้สมมติว่าฉันเป็นหนึ่งfile:

$ cat file
Hello
Welcome to
Unix
$

และฉันต้องการที่จะเพิ่มand Linuxในตอนท้ายของไฟล์จากนั้นecho " and Linux" >> fileจะถูกเพิ่มไปยังบรรทัดใหม่ แต่ฉันต้องการบรรทัดสุดท้ายเป็นUnix and Linux

ดังนั้นเพื่อหลีกเลี่ยงฉันต้องการลบอักขระบรรทัดใหม่ที่ท้ายไฟล์ ดังนั้นฉันจะลบอักขระบรรทัดใหม่ได้อย่างไรในตอนท้ายของไฟล์


6
อย่าลบออกเพียงใช้โปรแกรมแก้ไขข้อความ sed '$s/$/ and linux/'
123

คำตอบ:


27

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

sed '$ s/$/ and Linux/' <file >file.new &&
mv file.new file

สิ่งใดบน Linux ที่สามารถทำให้สั้นลงได้

sed -i '$ s/$/ and Linux/' file

หากคุณต้องการลบไบต์สุดท้ายในไฟล์ Linux (coreutils GNU ที่แม่นยำยิ่งขึ้น) ให้truncateคำสั่งซึ่งทำให้ง่ายมาก

truncate -s -1 file

POSIX ddวิธีที่จะทำมันขึ้นอยู่กับ ก่อนอื่นให้กำหนดความยาวของไฟล์จากนั้นตัดให้เหลือน้อยกว่าหนึ่งไบต์

length=$(wc -c <file)
dd if=/dev/null of=file obs="$((length-1))" seek=1

โปรดทราบว่าทั้งสองอย่างนี้จะตัดทอนไบต์สุดท้ายของไฟล์โดยไม่มีเงื่อนไข คุณอาจต้องการตรวจสอบว่าเป็นบรรทัดใหม่ก่อน:

length=$(wc -c <file)
if [ "$length" -ne 0 ] && [ -z "$(tail -c -1 <file)" ]; then
  # The file ends with a newline or null
  dd if=/dev/null of=file obs="$((length-1))" seek=1
fi

9
ดีมากวิธีที่จะเอาขึ้นบรรทัดใหม่ต่อท้ายperl -pi -e 'chomp if eof' myfileคือ เปรียบเทียบtruncateหรือddไม่ทิ้งคุณไว้กับไฟล์ที่เสียหายถ้าmyfileไม่มีบรรทัดใหม่ต่อท้าย
Hi-Angel

2
@ Hi-Angel ฉันขอแนะนำให้เขียนว่าเป็นคำตอบหรือไม่? ฉันคิดว่ามันจะเป็นคำตอบที่ดีมาก
Simon Forsberg

@SimonForsberg ขอบคุณเสร็จแล้ว
Hi-Angel

17

แม้ว่าคุณสามารถลบอักขระบรรทัดใหม่จากบรรทัดโดยtr -d '\n':

$ echo -e "Hello"
Hello
$ echo -e "Hello" | tr -d '\n'
Hello$

คุณสามารถลบอักขระบรรทัดใหม่ที่ท้ายไฟล์โดยใช้วิธีต่อไปนี้:

  1. head -c -1 file

    จากman head:

    -c, --bytes=[-]K
              print the first K bytes of each file; with the leading '-',
              print all but the last K bytes of each file
  2. truncate -s -1 file

    จากman truncate:

    -s, --size=SIZE
              set or adjust the file size by SIZE

    SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
    Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000).
    
    SIZE  may  also be prefixed by one of the following modifying characters: 
    '+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down to multiple of, '%' round up to multiple of.

คือhead -c -1 file | tee fileความปลอดภัยหรือไม่ จะไม่teeตัดไฟล์ก่อนเริ่มหรือไม่
iruvar

1
@ 1_CR แน่นอน ท่อทั้งสองด้านเริ่มขนานกันมันเป็นเรื่องของผู้ชนะการแข่งขัน เนื่องจากteeจะต้องเปิดไฟล์ในขณะที่headต้องอ่านและเขียนเนื้อหาteeในทางปฏิบัติจะชนะการแข่งขันยกเว้นบางครั้งสำหรับไฟล์ขนาดเล็กมาก
Gilles 'หยุดความชั่วร้าย'

2
สิ่งนี้จะไม่ลบบรรทัดใหม่ล่าสุดออก แต่จะลบบรรทัดใหม่ทั้งหมด IMO ค่อนข้างแตกต่างกันมาก
Hi-Angel

8

คุณสามารถบรรลุสิ่งนี้ด้วย Perl เป็น:

perl -pi -e 'chomp if eof' myfile

เมื่อเทียบกับtruncateหรือddสิ่งนี้จะไม่ทำให้คุณมีไฟล์ที่ใช้งานไม่myfileได้หากไม่มีบรรทัดใหม่ต่อท้าย

(คำตอบถูกสร้างขึ้นจากความคิดเห็นและขึ้นอยู่กับคำตอบนี้ )


ขอขอบคุณ! วิธีการลบแบบมีเงื่อนไขนี้จะขึ้นบรรทัดใหม่ที่สมบูรณ์แบบ
xer0x

2

ต่อไปนี้เป็นวิธีหนึ่งในsed- บน$บรรทัดสุดท้ายของไฟล์ค้นหาและแทนที่สิ่งใด ๆ ทุกอย่าง ( .*) ด้วย "สิ่งที่คุณจับคู่" ตามด้วย "และ Linux":

sed '$s/\(.*\)/\1 and Linux/' file

โซลูชันที่เรียบง่ายยิ่งขึ้นได้รับความอนุเคราะห์จากIsaacคือ:

sed '$s/$/ and Linux/' file

สิ่งนี้จะแทนที่ส่วนท้าย (สัญลักษณ์) ด้วยข้อความที่กำหนด


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