Як я можу редагувати останні n рядків у файлі?


10

Чи є команда, яка дозволить мені редагувати останні n рядків у файлі? У мене є декілька файлів, у яких все різна кількість рядків всередині. Але я хотів би змінити останні n рядків у кожному файлі. Мета - замінити коси крапками з комою в останніх n рядках. Але лише в останніх російських рядках.

Я не хочу видаляти жодні рядки, я просто хочу замінити кожну кому крапкою з комою в останніх n рядках у кожному файлі.

За допомогою команди sed я можу замінити останній рядок цією командою. Як описано тут: Як я можу видалити текст з останнього рядка файлу?

Але це дозволяє мені змінити самий останній рядок, а не останню n кількість рядків.


1
Просто використовуючи, sed '24,$s/,/:/g' filename де 24знаходиться стартовий рядок`
Валентин Байрамі

Відповіді:


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. Повинен бути швидшим на кілька наносекунд :)
садок

1
за винятком того, що wc -l inputвиводиться також ім’я файлу; ми хочемо лише підрахунку ліній
Jeff Schaller

Перша порада з редактором - це чудово і просто.
sku2003

Я фактично отримав допомогу зовсім з іншого боку. Це призвело до цього дивного фрагмента коду, який робить трюк, але довгий і дивний. Я думаю, що це деякі дивні речі, з якими ти можеш закінчитись, коли скласти рішення. У будь-якому випадку ваша красуня, коротша і менш складна, ніж моя: Код тут також працював:
sku2003

кішка 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 для заміни кожної коми крапкою з комою в останніх 50 рядках file.txt:

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

5

З GNU headта оболонкою, що нагадує Борна:

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

Ми перезаписуємо файл над собою. Це нормально тут транслітерації байт в байт , але не обов'язково , якщо зміна тягне за собою зміну розміру файлу (в цьому випадку, ви хочете замінити 1<> fileз > other-file && mv other-file file, наприклад).


1
Ось документи1<> , з якими я був незнайомий. Крім того, spongeз moreutils є хорошим інструментом для трубопроводів, де ви хочете перезаписати свої дані.
Майлз

1

Припустимо, ми хочемо замінити останні 7рядки наступної послідовності на сценарій оболонки та реалізацію 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 сторінки, що говорить:

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

Крок 4, також використовує подвійні лапки, як згадується тут .


Ну, 4 кроки непотрібні, якщо ми будемо використовувати відповідь Гоху так:

$ 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та подача на сед:

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

Це працює над файлом протягом останніх 20 рядків. Якщо ви хочете, щоб у вас були прямі файли, використовуйте файл:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.