I have a file located at: /Applications/Firefox.app/Contents/info.plist
. I am trying to find the line that contains LSUIElement
and then replace that whole line with <string>firefox</string>
.
This is what I got, so far, it does nothing:
line=“LSUIElement”
rep="<string>firefox</string>"
sed -e "s/${line}/${rep}/g" /Applications/Firefox.app/Contents/info.plist > /Applications/Firefox.app/Contents/info.plist.profilist
mv /Applications/Firefox.app/Contents/info.plist.profilist /Applications/Firefox.app/Contents/info.plist
With awk , you can do something like this:
awk '/LSUIElement/{i=NR+1}{if(NR==i){gsub(/1/,"0",$0)}}1' File > tmp && mv tmp File
Logic: if LSUIElement
is found, set variable i
to NR+1
(ie the next line /record number). As second part, if NR
(current record/line) is i
(previously saved), substitute 1
with 0
. Thus substitution will happen only in the line following the line with pattern LSUIElement
.
Let's simplify the problem for those, who don't have such a plist-file at hand.
echo -e "foo bar baz\nthe suspicious LSUIElement in line 2\nand some more garbage" > luis.txt
cat luis.txt
foo bar baz
the suspicious LSUIElement in line 2
and some more garbage
line=“LSUIElement”
rep="<string>firefox</string>"
So here we have problem 1: Slashes in sed expression normally separate the parts like in 's/a/b/g'.
sed -e "s/${line}/${rep}/g" luis.txt > luis2.txt
mv luis2.txt luis.txt
We first go for the low hanging fruit. Sed, at least Gnu-sed, has an option -i to alter the file in place. In the background, there might be a copy being made, since often the file will shrink or grow, so it is hard to avoid, but we don't need the redirection and mv:
sed -i "s/${line}/${rep}/g" luis.txt
You might even let sed produce a backup file. AFAIK sed doesn't need -e in normal cases, but it might be, that gnu-sed is special in that case. Test or read the man page.
Now for the hard part. We test without -i to avoid destruction. First test, first surprise:
line=“LSUIElement”
rep="<string>firefox</string>"
echo $line
# “LSUIElement”
echo $rep
# <string>firefox</string>
Why does line show quotes, but rep doesn't? Ah, these are typographical quotes? Is this of any importance? Then you should mention it, because it's easy to oversee. I decide to go without them until demand.
If we replace the / in the sed-expression with |, we can avoid collision with sed-syntax in the $rep variable:
sed "s|${line}|${rep}|g" luis.txt
foo bar baz
the suspicious <string>firefox</string> in line 2
and some more garbage
Here we replaced exactly the pattern, not the line.
sed "s|.*${line}.*|${rep}|g" luis.txt
foo bar baz
<string>firefox</string>
and some more garbage
This was replacing the whole line.
sed "s|${line}.*|${rep}|g" luis.txt
foo bar baz
the suspicious <string>firefox</string>
and some more garbage
This was replacing from pattern inclusive till the EOL.
If we want to replace something in the next line - well replace what? For example, the garbage ?
We can match on $line without replacing it, but calling a short series of 2 commands, 'n' for 'read next line' and perform our s-substitution there. Those commands have to be wrapped into {}. Since we don't need changing / to | in the former part, we switch back there:
sed "/${line}.*/{n;s|garbage|$rep|}" luis.txt
foo bar baz
the suspicious LSUIElement in line 2
and some more <string>firefox</string>
The command:
sed -i.bak "/${line}.*/{n;s|garbage|$rep|}" luis.txt
would create such a backupfile luis.txt.bak
With a pattern, as now noticed in the comment, this would look like:
sed -i.bak "/${line}.*/{n;s|<string>.*</string>|$rep|}" luis.txt
Decide, how specific (1, digits, doesn't matter) it has to be.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.