Reputation: 719
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.
Upvotes: 4
Views: 10223
Reputation: 58351
This might work for you:
sed '/^Filename:/s/\([^/]*\)\.[^.]*$/download.php?p=\1/' file
Upvotes: 0
Reputation: 141770
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.
Upvotes: 4
Reputation: 140227
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 '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile
awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile
$ 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 '/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 -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
Upvotes: 0
Reputation: 19020
You are looking for a tool called sed
:
sed -e "s|^(Filename: ./debs/)(.+).deb|\1download.php?p=\2|" < yourfile
Upvotes: 0
Reputation: 34145
Not in bash itself, but:
sed 's#Filename: \./debs/\(.*\)\.deb#Filename: ./debs/download.php?p=\1#' < the_file
Upvotes: 0
Reputation: 121702
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
.
Upvotes: 1