4

I have a file with thousands of lines. I'm looking for help to modify multiple lines which i were to choose.

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

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

I need a bash command to detect "Filename" then change them to something like this:

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

And it will loop till all "Filename" have been changed.

1
  • 2
    You should first show what you have tried, what code you have written, and only then ask for assistance. Do you want a fish or be able to fish? Commented Jan 1, 2012 at 20:19

6 Answers 6

4

This is a job for sed! From the GNU sed homepage:

Sed is typically used for extracting part of a file using pattern matching or substituting multiple occurrences of a string within a file.

Here is how you could do it:

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

Where:

  • /^Filename:/ looks for lines starting with (^) the text 'Filename:'
  • s!search!replace! replaces 'search' with 'replace' where 'search' is a regular expression
  • \1 is the string captured by the first matching group "\(...\)"
  • \2 is the string captured by the second matching group "\(...\)"

Demonstration:

$ 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

For tweaking this and for writing your own sed scripts, please consult the online documentation.

Sign up to request clarification or add additional context in comments.

1 Comment

@downvoter: Why? If there is something wrong with my answer, please point it out.
1

This is one solution:

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

First try it by not putting it the i option and pipe with less. Then re-add the i.

Comments

0

Not in bash itself, but:

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

Comments

0

You are looking for a tool called sed:

sed -e "s|^(Filename: ./debs/)(.+).deb|\1download.php?p=\2|" < yourfile

Comments

0

Here are improved answers with awk and sed.

Unlike the other answers, these work independent of what the 'Filename:' path is. That is to say, if you change './debs/' to './myDebs/' it will still work. All they require is that '.deb' file is at the end of the path

Sed

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 Output

$ 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 Output

$ 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

Comments

0

This might work for you:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.