ฉันจะแก้ไข n บรรทัดสุดท้ายในไฟล์ได้อย่างไร


10

มีคำสั่งให้ฉันแก้ไขบรรทัดสุดท้ายในไฟล์หรือไม่? ฉันมีไฟล์หลายไฟล์ซึ่งทั้งหมดมีจำนวนบรรทัดต่างกัน แต่ฉันต้องการแก้ไข n บรรทัดสุดท้ายในแต่ละไฟล์ เป้าหมายคือการแทนที่เครื่องหมายจุลภาคด้วยเครื่องหมายอัฒภาคในบรรทัดสุดท้าย n แต่จะอยู่ในบรรทัดสุดท้ายเท่านั้น

ฉันไม่ต้องการลบบรรทัดใด ๆ ฉันเพียงต้องการแทนที่เครื่องหมายจุลภาคทุกอันด้วยเครื่องหมายอัฒภาคในบรรทัดสุดท้าย n ในแต่ละไฟล์

การใช้คำสั่ง sed ฉันสามารถแทนที่บรรทัดสุดท้ายด้วยคำสั่งนี้ได้ ตามที่อธิบายไว้ที่นี่: ฉันจะลบข้อความในบรรทัดสุดท้ายของไฟล์ได้อย่างไร

แต่นี่ทำให้ฉันสามารถแก้ไขบรรทัดสุดท้ายเท่านั้นไม่ใช่บรรทัดสุดท้าย


1
เพียงแค่ใช้sed '24,$s/,/:/g' filename ที่24เป็นบรรทัดเริ่มต้น '
Valentin Bajrami

คำตอบ:


13

หากต้องการแทนที่เครื่องหมายจุลภาคด้วยเครื่องหมายอัฒภาคในบรรทัดสุดท้าย n ด้วยed:

n=3
ed -s input <<< '$-'$((n-1))$',$s/,/;/g\nwq'

แยกออกจากกัน:

  • ed -s = เรียกใช้อย่างเงียบ ๆ (อย่ารายงานไบต์ที่เขียนในตอนท้าย)
  • '$-'= จากท้ายไฟล์ ( $) ลบ ...
  • $((n-1)) = n-1 บรรทัด ...
  • ( $' ... '= อ้างถึงส่วนที่เหลือของคำสั่งเพื่อป้องกันคำสั่งจากเชลล์)
  • ,$s/,/;/g= ... จนกระทั่งถึงจุดสิ้นสุดของไฟล์ ( ,$) ค้นหาและแทนที่เครื่องหมายจุลภาคทั้งหมดด้วยเครื่องหมายอัฒภาค
  • \nwq = จบคำสั่งก่อนหน้าจากนั้นบันทึกและออก

หากต้องการแทนที่เครื่องหมายจุลภาคด้วยเครื่องหมายอัฒภาคในบรรทัดสุดท้าย n ด้วยsed:

n=3
sed -i "$(( $(wc -l < input) - n + 1)),\$s/,/;/g" input

แยกที่:

  • -i = แก้ไขไฟล์ "ในสถานที่"
  • $(( ... )) = ทำคณิตศาสตร์บางอย่าง:
  • $( wc -l < input) = รับจำนวนบรรทัดในไฟล์
  • -n + 1 = ย้อนกลับ n-1 บรรทัด
  • ,\$ = จาก n-1 บรรทัดจนกระทั่งสิ้นสุดไฟล์:
  • s/,/;/g = แทนที่เครื่องหมายจุลภาคด้วยเครื่องหมายอัฒภาค

สามารถแทนที่ด้วยwc -l < input wc -l inputควรจะได้เร็วขึ้นโดยไม่กี่นาโนวินาที :)
gardenhead

1
ยกเว้นว่าจะwc -l inputส่งออกชื่อไฟล์เช่นกัน เราแค่ต้องการนับบรรทัด
Jeff Schaller

คำแนะนำแรกที่มี ed ดีและเรียบง่าย
sku2003

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

cat input.file | sed 's /, /, \ n / g' | sed -n '1! G; h; $ p' | awk -vn = 2 'NR <= n {gsub (",", ";", $ 0)} {print}' | sed -n '1! G; h; $ p' | sed '/ ^ \ s * $ / d'> output.file
sku2003

6

โซลูชันที่ใช้tacและsedเพื่อแทนที่คอมมาทั้งหมดด้วยเครื่องหมายอัฒภาคใน file.txt 50 บรรทัดสุดท้าย:

tac file.txt | sed '1,50s/,/;/g' | tac

5

ด้วย GNU headและเชลล์คล้าย Bourne:

n=20
{ head -n -"$n"; tr , ';'; } < file 1<> file

เรากำลังเขียนทับไฟล์ทับตัวมันเอง ไม่เป็นไรที่นี่สำหรับการทับศัพท์แบบไบต์ต่อไบต์ แต่ไม่จำเป็นว่าการดัดแปลงจะหมายถึงการเปลี่ยนขนาดของไฟล์ (ในกรณีนี้คุณต้องการแทนที่1<> fileด้วย> other-file && mv other-file file)


1
นี่คือเอกสาร1<>ที่ฉันไม่คุ้นเคย นอกจากนี้spongeจากmoreutilsเป็นเครื่องมือที่ดีสำหรับท่อที่คุณต้องการเขียนทับข้อมูลของคุณ
ไมล์

1

สมมติว่าเราต้องการแทนที่7บรรทัดสุดท้ายของลำดับต่อไปนี้ด้วย shell script และการนำ GNU ไปใช้sed:

$ seq 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

ขั้นตอนที่ 1 : ให้ลำดับบรรทัดสุดท้ายเป็นดังนี้ ดูที่นี่และที่ :

$ lastLine=`seq 20|sed -n '$='`

$ echo $lastLine 
20

ขั้นตอนที่ 2 : ให้กำหนดจำนวนบรรทัด (ในตอนท้ายของลำดับ) เราตั้งใจจะแก้ไข:

$ numberOfLines=7

$ echo $numberOfLines 
7

ขั้นตอนที่ 3 : ให้คำนวณบรรทัดเริ่มต้นตามตัวแปรก่อนหน้าดังนี้ ลองดูที่นี่ :

$ startLine=`expr $lastLine - $numberOfLines + 1`

$ echo $startLine 
14

ขั้นตอนที่ 4 : ตอนนี้เราสามารถแทนที่ลำดับ 7 บรรทัดสุดท้ายด้วยอย่างอื่นดังต่อไปนี้ ลองดูที่นี่ :

$ seq 20|sed -e "$startLine,+$numberOfLines{s/[12]/WoW/}"
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

ขั้นตอนที่ 4 ใช้ส่วน 4.4 ของหน้า manที่แจ้งว่า:

'ADDR1,+N'
     Matches ADDR1 and the N lines following ADDR1.

ขั้นตอนที่ 4 นอกจากนี้ยังมีการใช้ราคาสองครั้งเป็นที่กล่าวถึงที่นี่


4 ขั้นตอนนั้นไม่จำเป็นถ้าเราใช้คำตอบของ Gohuเช่นนี้:

$ seq 20 |tac|sed -e '1,7{s/[12]/WoW/}'|tac
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

0

ใช้tailและท่อเพื่อ sed:

tail -n 20 file | sed 's/,/;/g'

สิ่งนี้ใช้ได้กับไฟล์สำหรับ 20 บรรทัดล่าสุด หากคุณต้องการให้เจ้า canges ตรงไปยังการใช้ไฟล์:

tail -n 20 file | sed -i 's/,/;/g'

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