sed or egrep regex multiple line - sed

I have a LaTeX-File like this:
\usepackage[colorlinks,
citecolor=black,
urlcolor=black
]
{hyperref}
\usepackage{ngerman}
and i have to output it like this:
hyperref:colorlinks,citecolor=black,urlcolor=black
ngerman:
I may only use sed and egrep, not awk and perl.
How do I do this?

You can pipe sed command into other sed commands to use a layered approach.
Remove newlines
Convert } into }\n
Convert \usepackage[optional]{packagename} into packagename:[optional]
Remove the spaces and brackets
Here is the script:
sed ':a;N;$!ba;s/\n/ /g' file.latex | sed 's/}/}\n/g' | sed 's/\\usepackage[[:space:]]*\(.\+\)\?[[:space:]]*{\(.\+\)}/\2:\1/' | sed 's/\[//g;s/\]//g;s/[[:space:]]//g'
Here is the result:
hyperref:colorlinks,citecolor=black,urlcolor=black
ngerman:
The first command is taken verbatim from How to insert a newline in front of a pattern?. Some of these commands can be combined, but I find it easier to understand when there is a separate command for each step. If your latex files are small, time should not be a problem.

Related

Replacing the test with sed

I'm trying to replace the text using the sed, but it's showing some error. Not getting where I'm getting wrong.
sed -i 's/process.env.REDIRECT_URI/http:\/\/test-domain.apps.io/\callback/g' input.txt
Have this :
process.env.REDIRECT_URI
Replace this with :
http://test-domain.apps.io
Try:
sed -i 's/process.env.REDIRECT_URI/http:\/\/test-domain.apps.io/g' input.txt
Notes:
The original command has a spurious string /\callback. All that was needed to make the code work was to remove it.
. is a wildcard. If you want to be sure that you are matching periods, they should be escaped:
sed -i 's/process\.env\.REDIRECT_URI/http:\/\/test-domain.apps.io/g' input.txt
Sometimes, its clearer if one doesn't have to escape /. One can use a separator of one's choice. For example, use #:
sed -i 's#process\.env\.REDIRECT_URI#http://test-domain.apps.io#g' input.txt
If you did want /callback in the output, use:
sed -i 's/process\.env\.REDIRECT_URI/http:\/\/test-domain.apps.io\/callback/g' input.txt
or:
sed -i 's#process\.env\.REDIRECT_URI#http://test-domain.apps.io/callback#g' input.txt

Better way to fix mocha lcov output using sed

Due to the know prob of mocha-lcov-mocha breaking file paths, I need to fix the current output paths that looks like this:
SF:Vis/test-Guid.coffee
SF:Vis/Guid.coffee
SF:Vis/test-Vis-Edge.coffee
SF:Vis/Vis-Edge.coffee
into
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
I'm not very good with sed, but I got it to work using:
mocha -R mocha-lcov-reporter _coverage/test --recursive | sed 's,SF:,SF:src/,' | sed s',SF.*test.*,SF:test//&,' | sed s',/SF:,,' | sed s',test/src,test,' | ./node_modules/coveralls/bin/coveralls.js
which is basically doing 4 sed commands in sequence
sed 's,SF:,SF:src/,'
sed s',SF.*test.*,SF:test//&,'
sed s',/SF:,,'
sed s',test/src,test,'
my question is if there is a way to do with this one sed command, or use another osx/linux command line tool
Initially put "src/" after every ":" and then if "test" is found on the line replace "src" with "test":
$ sed 's,:,:src/,;/test/s,src,test,' file
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
You could put all the sed commands in a file, one line per command, and just use "sed -e script". But if you just want it on a single command-line, separate with semicolons. This works for me:
sed 's,SF:,SF:src/,;s,SF.*test.*,SF:test//&,;s,SF:,,;s,test/src/,test,'
sed command
sed '\#test#!{s#SF:Vis/#SF:src/Vis/#g};\#SF:Vis/test#{s#SF:Vis/test#SF:test/Vis/test#g};' my_file
Here is an awk version:
awk -F: '/SF/ {$0=$1FS (/test/?"test/":"src/")$2}1' file
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
How it works:
awk -F: ' # Set field separator to ":"
/SF/{ # Does line start with "SF"?
$0=$1FS (/test/?"test/":"src/")$2 # Recreat String by adding "test" if line contains "test", else "src"
}
1 # Print all lines
' file # read the file

How to use sed in order to search ^A and replace it

I would like to use (GNU) sed to do a simple search and replace. The issue is that I'm searching for a special character and it might be the reason it failed for me.
The input is:
^A9=139^A35=V^A34=9^A49=xxxx^A52=20140527-06:18:43.759^A5
and I want to replace the ^A with ;. I used:
sed -i '/s/^A/;/g' file.log
but I didn't get anything.
Your command should be,
sed -i 's/\^A/;/g' file
Command you tried,
sed -i '/s/^A/;/g' file.log
| |
| |______________You have to escape this special character. Because in general(regex) it means the starting point.
[No need to use `/` before s]
Example:
$ sed 's/\^A/;/g' file
;9=139;35=V;34=9;49=xxxx;52=20140527-06:18:43.759;5
^ has a special meaning with regular expressions. Use \^ (or potentially \\^, depending on how bash escapes things, I never quite remember it).

using sed for substitution in next line

I am working on sed command to translate some text into another text.
cat text
<strong>ABC
</strong>
Commnad:
sed -e 's|<strong>(.*?)</strong>|//textbf{1}|g'
Expected Outcome: \textbf{ABC}
but using above script i cannot convert it into expected output since there is new line between the tags. How to handle such cases?
This might work for you (GNU sed):
sed -r '$!N;s|(<)(strong>)([^\n]*)\n\s*\1/\2|//textbf{\3}|;P;D' file
or
sed '$!N;s|\(<\)\(strong>\)\([^\n]*\)\n\s*\1/\2|//textbf{\3}|;P;D' file
sed -e 'N;s|<strong>\(.*\?\)\n</strong>|\/textbf{\1}|g'
as said by CodeGnome and David Ravetti, the N flag allows for multi-line patterns.

replace ';' with ';\n'

How can I replace ; with ;\n (semicolon followed by a newline) in sed?
I've tried building off of
sed s/;/\\n/g file
and
sed -e '/;/G' file
but I can't get either to work
You need to cheat a bit: in bash you can say
sed $'s/;/;\\\n/g'
or, portably (POSIX):
sed "s/;/;$(printf '\\\n')/g"
sed does not portably/reliably handle backslash-escapes anywhere but in the pattern, and even there it's limited (POSIX only requires that \n be handled, not \t or the others). Note that you also need a backslash before the \n so sed doesn't read it as the end of the command.
sed -ie 's/;/;\n/g' <file>
That's assuming you want to do it inline in the file, remove the "i" and just use "-e" if that's not the case.