Как заменить несколько строк с помощью Bash? - PullRequest
3 голосов
/ 01 января 2012

У меня есть файл с тысячами строк.Я ищу помощь, чтобы изменить несколько строк, которые я должен был выбрать.

Package: com.xyz.abc
Version: 1.0
Filename: ./debs/abc.deb

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./debs/def.deb

Мне нужна команда bash, чтобы определить «Имя файла», а затем изменить их на что-то вроде этого:

Package: com.xyz.abc
Version: 1.0
Filename: ./debs/download.php?p=abc

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./debs/download.php?p=def

И он будет повторяться до тех пор, пока не будут изменены все «Имя файла».

Ответы [ 6 ]

4 голосов
/ 01 января 2012

Это работа для sed!На домашней странице GNU sed :

Sed обычно используется для извлечения части файла с использованием сопоставления с образцом или замены нескольких вхождений строки в файле.

Вот как это можно сделать:

sed '/^Filename:/s!\(./debs/\)\(.*\).deb!\1download.php?p=\2!' /path/to/input > /path/to/output

Где:

  • /^Filename:/ ищет строки, начинающиеся с (^) текста 'Имя файла:'
  • s!search!replace! заменяет' search 'на' replace ', где' search '- регулярное выражение
  • \1 - строка, захваченная первой соответствующей группой "\(...\)"
  • \2 - строка, захваченная второй подходящей группой "\(...\)"

Демонстрация:

$ echo 'Package: com.xyz.abc
Version: 1.0
Filename: ./debs/abc.deb

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./debs/def.deb' | sed '/^Filename:/s!\(./debs/\)\(.*\).deb!\1download.php?p=\2!' 
Package: com.xyz.abc
Version: 1.0
Filename: ./debs/download.php?p=abc

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./debs/download.php?p=def

Для настройки этого и для написания собственногоsed скриптов, пожалуйста, обратитесь к онлайн документации .

1 голос
/ 01 января 2012

Это одно решение:

perl -pi -e '/^Filename:/ and s,debs/([^.]+)\.deb\s*$,debs/download.php?p=$1,' thefile

Сначала попробуйте, не устанавливая параметр i и добавьте less. Затем повторно добавьте i.

0 голосов
/ 02 января 2012

Это может работать для вас:

 sed '/^Filename:/s/\([^/]*\)\.[^.]*$/download.php?p=\1/' file
0 голосов
/ 01 января 2012

Вот улучшенные ответы с awk и sed.

В отличие от других ответов, они работают независимо от того, какой путь 'Filename:'. То есть, если вы измените «./debs/» на «./myDebs/», он все равно будет работать. Все, что им требуется, это то, что файл .deb находится в конце пути

Сед

sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile

AWK

awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile

Input

$ cat ./infile
Package: com.xyz.abc
Version: 1.0
Filename: ./debs/abc.deb

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./MyDebs/def.deb

sed Выход

$ sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile
Package: com.xyz.abc
Version: 1.0
Filename: ./debs/download.php?p=abc

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./MyDebs/download.php?p=def

awk Вывод

$ awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile
Package: com.xyz.abc
Version: 1.0
Filename: ./debs/download.php?p=abc

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./MyDebs/download.php?p=def
0 голосов
/ 01 января 2012

Вы ищете инструмент под названием sed:

sed -e "s|^(Filename: ./debs/)(.+).deb|\1download.php?p=\2|" < yourfile
0 голосов
/ 01 января 2012

Не в самом bash, но:

sed 's#Filename: \./debs/\(.*\)\.deb#Filename: ./debs/download.php?p=\1#' < the_file
...