Executing edits in parallel rather than sequentially - sed

I want to apply a large number of edits to a file in parallel. That is I don't want the subsequent edit commands to modify already modified lines as they would if they pass through a sed pattern space.
Any tips?

This might work for you (GNU sed):
sed 's/fred/wilma/g;t;s/wilma/betty/g' file
Use the fact that a substitution has taken place as a way of preventing further substitutions on that line. The t command will bail out if a substitution has succeeded.

Related

Replace selectedText with Task output in Visual Studio Code

I have a task which passes highlighted text (${selectedText}) to an external script and the output gets printed in the terminal.
Is there anyway to have that script output replace the highlighted text?
:)
Even saving to a new file and merging into the existing file would be fine, that seems far more complicated though.
I found I can do this in a slightly more round about way than I intended. VSCode Tasks can be shell operations, so I solved the problem using bash shell tools like sed and awk.
1.) Have the output of my script get saved to a temporary file.
2.) Using sed -i I can strategically erase the highlighted lines (after determining the range of lines highlighted).
3.) Then using AWK I can paste the temp file output into specific lines in my primary file. I could do it all in sed or awk but found it easier to use both.
4.) Clean up by deleting the temp file.
So there is no all in one nice VSCode solution that I could find, but it is doable.

How can I replace multiple lines with sed

I want to write a simple Markdown to LaTex converter and chose sed as the core component of the converter. It was suitable for everything until now when I hit the following problem: I want to convert a markdown code block (3 backticks) into a LaTex listing. The problem is that I want to work on multiple lines here. I tried the following command but it does not work since sed is processing the input line by line:
sed -E 's/```([[:print:]]*)```/\\begin{lstlisting}/1\\end{lstlisting}/g'
Another idea would be to try to only search and replace only the three backticks, but since every other occurrence needs to be replaced with \end{lstlisting} I do not know if it is possible. A hacky way would be to use three backticks for the start of the code block and four for the end, but that is quite a dirty solution in my opinion.
This might work for you (GNU sed):
sed -E '/^```/{:a;N;/\n```$/!ba
s/^```(.*)```$/\\begin{lstlisting}\1\\end{lstlisting}/}' file
On encountering ``` at the beginning of a line, gather up all lines untill another such line and replace those lines by \begin{lstlisting} and \end{lstlisting}.

i would like to extract the pspictures from a tex file and put the in another file so they can processed into ps or pdf files really easily

I have a list of files .tex file that contain fragments in the tex that build ps pictures which can be slow to process.
There are multiple fragments across multiple files and the end delimiter is \end{pspicture}
% this is the beginning of the fragment
\begin{pspicture}(0,0)(23,5)
\rput{0}(0,3){\crdKs}
\rput(1,3){\crdtres}
\rput(5,3){\crdAh}
\rput(6,3){\crdKh}
\rput(7,3){\crdsixh}
\rput(8,3){\crdtreh}
\rput(12,3){\crdQd}
\rput(13,3){\crdeigd}
\rput(14,3){\crdsixd}
\rput(15,3){\crdfived}
\rput(16,3){\crdtwod}
\rput(20,3){\crdKc}
\rput(21,3){\crdfourc}
\end{pspicture}
I would like to extract the fragments.
I am not sure how to go about this? can awk do this or sed?
They seem to work line by line, rather than work on the whole fragment.
I am not really looking for a solution just a good candidate tool.
sed -En '/^\\begin\{pspicture\}.*$/,/^\\end\{pspicture\}.*$/p' file
Utilising sed with -E for regular expressions.
Use //,// to determine start and ending regular expressions and print all lines from the start to the end.

diff ignore certain pattern in the file

I want to make diff between two files which contains lines beginning with "line_$NR". I want to make diff between the files making abstraction of the presence of "lines_$NR" but when the differences are printed I want lines_$NR to be displayed.
It is possible to do that?
Thanks.
I believe in this case, you have to preprocess your iput files to remove /^line_[0-9]*/, diff the resulting files, then recombine the diff output with the removed words according to line numbers in diff output.
Python's difflib should be very handy here, or same from perl. If you want to stick to shell, I suppose you could get by with awk.
If you don't need exact output, perhaps you can use diff's --line-format=... directive to inject actual line number in a diff, rather than the word you removed in preprocessing step.

Read and delete text between two strings in perl

I need a way to read and delete text between two different strings found in some file, then delete the two strings. Like a "cut command." I would like to have the text stored in a variable.
I saw the post about reading text between two strings, but I could not figure out how to delete it as well.
I intend to execute the stored text in bash. Efficiency is desirable. This script is not going to be used on large files, but it may be executed many times sequentially so the faster the script works the better.
The stored text will usually have special characters.
Thanks
Specify the beginning and ending strings via the environment, and the file to use on the perl command line:
export START_STRING='abc def'
export END_STRING='ghi jkl'
perl -0777 -i -wpe's/\Q$ENV{START_STRING}\E(.*)\Q$ENV{END_STRING}\E/s;print STDERR $1' file_to_use 2>savedtext