Reputation: 957
I have a list of C++ source files, which have the following structure:
// A lot of stuff
#include <current/parser/support/base.hpp>
// ...
#include <current/parser/iterators/begin.hpp>
// ...
I need to replace lines like
#include <current/parser/support/base.hpp>
with
#include <support_base.hpp>
Namely, omit the current/parser
and replace the separator (/
) with _
.
Is this possible to do with bash sed or a scripting language?
EDIT: Sorry, forgot to mention that I want to replace anything like
#include <current/parser/*/*/*/*>
Anything can go after current/parser
, and with any depth.
Upvotes: 2
Views: 401
Reputation: 35198
Using a perl one-liner
perl -i -pe 's{^#include <\Kcurrent/parser/([^>]*)}{$1 =~ y|/|_|r}e;' file.cpp
Or without regex features greater than perl 5.10
perl -i -pe 's{(?<=^#include <)current/parser/([^>]*)}{join "_", split "/", $1}e;' file.cpp
Switches:
-i
: Edit files in place (makes backup if extension supplied)-p
: Creates a while(<>){...; print}
loop for each line in your input file. -e
: Tells perl
to execute the code on command line. Upvotes: 0
Reputation: 75498
Using sed:
sed -i -e '/#include <current\/parser\/support\/base\.hpp>/{ s|current/parser/||; s|/|_|; }' -- file1 file2 file3
Edit:
sed -i -e '/#include <current\/parser\/.*>/{ s|current/parser/||; s|/|_|g; }' -- file1 file2 file3
Would remove currrent/parsers/
and replace all /
with _
. Example result file:
// A lot of stuff
#include <support_base.hpp>
// ...
#include <iterators_begin.hpp>
// ...
Some details:
/#include <current\/parser\/.*>/ -- Matcher.
s|current/parser/|| -- Deletes `current/parser/` in matched line.
s|/|_|g -- Replaces all `/` with `_` in same line.
Upvotes: 3
Reputation:
You can try it with sed
and -r
for regular expression:
sed -r 's|#include <current/parser/support/base\.hpp>|#include <support_base.hpp>|g' file
But using this way could kill your code. So be carefull :)
Upvotes: 0
Reputation: 71548
Going with Tcl:
# Open the file for reading
set fin [open filein.c r]
# Open the file to write the output
set fout [open fileout.c w]
# Loop through each line
while {[gets $fin line] != -1} {
# Check for lines beginning with "^#include <current/parser/"
#
# ^ matches the beginning of the line
# ([^>]*) matches the part after "#include <current/parser/" and stores it
# in the variable 'match'
if {[regexp {^#include <current/parser/([^>]*)>} $line - match]} {
# the edited line is now built using the match from above after replacing
# forward slashes with underscores
set newline "#include <[string map {/ _} $match]>"
} else {
set newline $line
}
# Put output to the file
puts $fout $newline
}
# Close all channels
close $fin
close $fout
Output with the provided input:
// A lot of stuff
#include <support_base.hpp>
// ...
#include <iterators_begin.hpp>
// ...
Demo on codepad (I edited the code a bit since I can't have a channel open to read/write in files there)
Upvotes: 3