I have a frequent pattern on my text, say
(Eq. \ref{XXXX})
where XXXX is some word, and I'd like to change all this simply to
\refp{XXXX}
I can't make it work through CtrlF, even with Regex. The syntax
\(Eq. \\ref{.*}\)
works for finding the occurences (if with some bugs...) but the traditional backreferencing
\\refp{\1}
won't work for the replacement.
I tried to create a custom command with the atom-shell-commands package, the idea would be to use sed on the current selection. But the package won't accept octal escape sequences.
Any thoughts?
The replacement tokens use a $ sigil, not \. So you want $1, $2, $3, ...
The replacement in this case should be:
\\refp{$1}
As is common with regex matching, these tokens match the contents of paren groups, from left to right. So you need to add matching parens also. Your match string would be:
\(Eq. \\ref{(.*)}\)
Note there are parens around the .* match, so whatever is inside those parens is stored in $1. If there were a second and third set of parens, those would become $2 and $3.
Related
At the moment with - grep -row "ASC.*\| DEFG.*\|"
I get below result:
/data/de_pgms/programs/00_individuals/programs/parts:ASC */
/data/de_pgms/programs/00_individuals/programs/parts:ASC.LKP_DAILY_DATES
/data/de_pgms/programs/00_individuals/programs/parts:DEFG Analysts\DATA_REQUEST.XLSX";
/data/de_pgms/programs/00_individuals/programs/parts:DEFG_AA/Constrained Supplier List";
How do i make sure I only get results such as
/data/de_pgms/programs/00_individuals/programs/parts:ASC.LKP_DAILY_DATES
/data/de_pgms/programs/00_individuals/programs/acm:DEFG.EDS_MONTHLY_RUN
Question:
how can I use grep to get all files and words in each file which contain the suffix ASC. or DEFG. or CDW.?
grep -e ":ASC\..*$\|:DEFG\..*$" file
Try this. It changes your pattern to a regular expression adding more context. most of it is literal like your expression however the $ at the end being an important feature to say the line ends here. prepending the ":" to the expressions prevents some false matches too. finally the .* says to match any one or more of any character.
We have requirement where i need to replace part of param value in our configuration file.
Example
key1=123-456
I need to replace the value after hyphen with new value.
I got command which is being used in other projects but i am not sure how it works.
Command
[test]$ cat test_sed_key_value.txt
key1=123-456
[test]$ sed -i -e '/key1/ s/-.*$/-789/' test_sed_key_value.txt
[test]$
[test]$ cat test_sed_key_value.txt
key1=123-789
[test]$
It will be helpful if some one can explain how the above command or is there a simpler way to do this using sed.
Here is a list of parts of that commandline, each followed by a short explanation:
sed
which tool to use
-i
flag: apply the effect directly to the processed file (whithout creating a copy of the input file)
-e
expression parameter: the sed code to apply follows
/key1/
"address": only process lines on which this regex applies, i.e. those containing the text "key1"
s/replacethis/withthis/
command: do a search-and-replace, "replacethis" and "withthis" are the next to explanations
-.*$
regex: (what is actually in the commandline instead of "replacethis") a regular expression representing a "minus" followed by anything, in any number, until the end of the line
-789
literal: (what is actually in the commandline instead of "withthis") simply that string "-789"
test_sed_key_value.txt
file parameter: process this file
I cannot think of any way to do this simpler. The shown command already uses some assumptions on the formatting of the input file.
I'd add to Yunnosch's answer that here the "replacethis" is a regexp:
-.*$
See here for an overview of the syntax of sed's regular expressions by Gnu.
Asterisk means a repetition of the previous thing, dot means any character, so .* means a sequence of characters.
$ is the end of the line.
You might want to be a bit more restrictive, since here you'd lose something in a line like this one for instance:
key1=123-456, key2=abc-def
replacing it by:
key1=123-789
removing completely the key2 part (since the .* takes all characters after the first dash until end of line).
So depending on the format of your values, you might prefer something like
-[0-9]*
(without the $), meaning a sequence of numbers after the -
or
-[0-9a-zA-Z_]
meaning a sequence of numbers or letters or underscore after the -
So I've been given an assignment and the question is:
What command would you enter to see 5-letter words that begin with 'd' (upper or lower-case), followed by a lower-case vowel, and ending in 's'?
grep '^[Dd][aeiouy]..[s]' /usr/share/dict/words
^[Dd] Means that the first letter is D or d. Perfect.
[aeiouy] Means that the next letter will be one of those. Perfect.
Two dots means that the next two characters can be anything that they want. Perfect.
And s because it ends in an s. Perfect.
But when I hit enter, I'm getting things like debasements and debases. Not only are my parameters for grep being ignored, but it is reaching for too many words already, and I can't figure out what I've done wrong.
You need to anchor the end. Like this:
grep '^[Dd][aeiouy]..[s]$' /usr/share/dict/words
Otherwise you're matching all words that start with '[Dd][aeiouy]..s' which is why you get things like "dumpster"
I believe ^ and $ are string terminators, so unless the line contains ONLY the word you're looking for, you won't find it. It only works on the dictionary file but not in general files, if you try. You should use \b on both sides as they're word boundaries.
\b[Dd][aeiouy]..[s]\b
But, grep will not return you only these words. It will return you the whole line that matches the expression, for example:
~$ grep "\b[Dd][aeiouy]..[s]\b" test
aacd danis daniel danis Dunns daniedanilsanielfk
In this case, just use the parameter -o, to print only matching words, one each line.
~$ grep -o "\b[Dd][aeiouy]..[s]\b" test
danis
danis
Dunns
For the file james, when I run this command:
cat james | grep ["."]
I get only the lines that contain a dot.
How do I get only the lines that end with a dot?
To find lines that end with a . character:
grep '\.$' james
Your cat command is unnecessary; grep is able to read the file itself, and doesn't need cat to do that job for it.
A . character by itself is special in regular expressions, matching any one character; you need to escape it with a \ to match a literal . character.
And you need to enclose the whole regular expression in single quotes because the \ and $ characters are special to the shell. In a regular expression, $ matches the end of a line. (You're dealing with some characters that are treated specially by the shell, and others that are treated specially by grep; the single quotes get the shell out of the way so you can control what grep sees.)
As for the square brackets you used in your question, that's another way to escape the ., but it's unusual. In a regular expression, [abc] matches a single character that's any of a, b, or c. [.] matches a single literal . character, since . loses its special meaning inside square brackets. The double quotes you used: ["."] are unnecessary, since . isn't a shell metacharacter -- but square brackets are special to the shell, with a similar meaning to their meaning in a regular expression. So your
grep ["."]
is equivalent to
grep [.]
The shell would normally expand [.] to a list of every visible file name that contains the single character .. There's always such a file, namely the current directory . -- but the shell's [] expansion ignores files whose names start with .. So since there's nothing to expand [.] to, it's left alone, and grep sees [.] as an argument, which just happens to work, matching lines that contain a literal . character. (Using a different shell, or the same shell with different settings, could mess that up.)
Note that the shell doesn't (except in some limited contexts) deal with regular expressions; rather it uses file matching patterns, which are less powerful.
You need to use $, which signals the end of the line:
cat james | grep ["."]$
This also works:
cat james |grep "\.$"
You can use a regular expression. This is what you need :
cat james | grep "\.$"
Look at grep manpage for more informations about regexp
Getting errors from the following sed command:
echo 20130521_OnePKI_p107336_APP.pfx | sed -e 's/_\([pP][0-9]+\)_/\1/'
Instead of returning p107336, it is returning the full filenam 20130521_OnePKI_p107336_APP.pfx.
Any ideas why this is happening, and how I can restrict the output to only the pattern I would like?
The captures should be escaped parentheses and you can use case-insensitive match i, also, you are replacing the capture part with the captured part so no changes are made. This one matches the entire line and replaces it with the captured pattern:
sed -e 's/.*_\([pP][0-9][0-9]*\)_.*/\1/'
An easier way might be to use grep:
echo 20130521_OnePKI_p107336_APP.pfx | egrep -o "[pP][0-9]+"
The "-o" tells grep to only print the matching part of the input.
The regex [pP][0-9]+ in principle matches any substring that begins with either p or P followed by one or more digits. The string "20130521_OnePKI_p107336_APP.pfx" has a substring matching that pattern so the whole string matches the regex.
When grouping with parenthesis around the whole regex on the left side and referring to it on the right side like you did in 's/([pP][0-9]+)/\1/' you're basically saying "replace the match with itself", which will naturally result in the same string as had in the first place.
What you need here is to match the whole string from beginning and then group a part of that string, as already indicated. Then you can refer to that part on the right side to extract it from the bigger string.
You will need to appropriately escape the expression when working in a shell.
You must escape parens and +. Also match all the string and substitute all it only with the part you wish (.* before and end your string):
... | sed -e 's/^.*\([pP][0-9]\+\).*$/\1/'