how to use bash to find text string like--> "PROVISIONING_PROFILE[sdk=iphoneos*]" <--this string has many special characters - xcode

As the title says, i'd like to find a string in a text, but the string is special.
The text may like this:
{
PREBINDING = NO;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "22B333C5-6D7A-4A76-81F2-12A045DAE44C";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
}
( Additionally, if you are a ios developer, you may know that the text example is from XXX.xcodeproj/project.pbxproj )
I need to find and delete this line of text:
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "22B333C5-6D7A-4A76-81F2-12A045DAE44C";
In this line, it has quotes("), has brackets([ ]), has star(*), also has space( ). When i try to find this line using code below:
provisionStr="22B333C5-6D7A-4A76-81F2-12A045DAE44C"
fileDir=project.pbxproj
totalLineStr=`grep $provisionStr $fileDir`
sed -i "" "s#$provisionStr##" $fileDir
This bash code does not work. Please help me, i'm just beginning to learn to use bash.

sed substitute with nothing:
s(for substitute)/string_to_match/new_string_or_empty_to_remove/g(for global/all document)
sed 's/\"PROVISIONING_PROFILE\[sdk=iphoneos\*\]" = \"22B333C5-6D7A-4A76-81F2-12A045DAE44C\";//g'
escape double quotes, asterix and brackets using \

It sounds like all you want to do is:
grep -v '"22B333C5-6D7A-4A76-81F2-12A045DAE44C"' file
If you ever did want to search for a string in a file instead of search for matches to an RE in a file, then you'd just do this, for example:
$ awk -v str='"PROVISIONING_PROFILE[sdk=iphoneos*]"' 'index($0,str)' file
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "22B333C5-6D7A-4A76-81F2-12A045DAE44C";
$ awk -v str='"PROVISIONING_PROFILE[sdk=iphoneos*]"' '!index($0,str)' file
{
PREBINDING = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
}
Do not try escaping all the RE metacharacters and then do an RE comparison as that makes no sense. If you want to look for an RE then do an RE comparison but if you want to look for a string do a string comparison, it's that simple.

Related

Sed fails to update long text

Consider test file csf.conf:
CC_DENY = ""
Running the command:
sed -i -E 's/(CC_DENY *= *")[^"]+/\1AR,BE,CL,CN,CO,CS,ES,FR,GR,HK,IT,KO,PA,PE,PH,PL,RS,RU,SG,SK,TH,UA,VN,AE,AF,AL,AS,AZ,BA,BD,BF,BH,BJ,BN,CI,DJ,EG,EH,ER,ET,GM,GN,GW,IQ,IR,IS,JO,KG,KM,KW,KZ,LB,LY,MC,MK,ML,MR,MV,MY,NE,NG,OM,PK,PS,QA,SA,SD,SL,SN,SO,SY,TD,TJ,TM,TN,TR,UZ,XK,YE,YT/g' csf.conf
Does not replace the match inside the file. Output should look like this:
CC_DENY="AR,BE,CL,CN,CO,CS,ES,FR,GR,HK,IT,KO,PA,PE,PH,PL,RS,RU,SG,SK,TH,UA,VN,AE,AF,AL..."
Sed v4.2.2, same result on Debian 8, and Centos 7
This has nothing to do with long text, your regexp just doesn't match the content of your file. Change [^"]+ to [^"]* so it'll match even when there's nothing between the double quotes "". Look:
$ cat csf.conf
CC_DENY = ""
$ sed -E 's/(CC_DENY *= *")[^"]+/\1foo/' csf.conf
CC_DENY = ""
$ sed -E 's/(CC_DENY *= *")[^"]*/\1foo/' csf.conf
CC_DENY = "foo"
wrt the comment below from the OP that this sed command works:
$ cat file
LF_SPI = ""
$ sed -E 's/(LF_SPI *= *\")[^\"]+/\1blah/g' file
LF_SPI = ""
Clearly and predictably, no it does not. It simply can't because the regexp metacharacter + means 1 or more so [^\"]+ states there must be at least one non-" after the " and that just does not exist in the input file. There is no reason to escape the double quotes btw.
Suppose the current variable value in the file is empty. Then your regular expression doesn't match because [^"]+ means "any character, except double quote repeated one or more times".
You might fix it by replacing + quantifier with * (zero or more times). But suppose the value contains a double quote:
CC_DENY = "\""
Then the [^"]* will match everything until it gets to the double quote within the value.
Thus, I suggest the following command:
# Put the variable value here
value='AR,BE\\" ... YE,YT';
sed -i -r 's/^( *CC_DENY *= *").*"/\1'"$value"'"/' csf.conf
Also note, that the expression above uses an anchor for the beginning of the line. Otherwise, it will fail to match as expected, if such a CC_DENY = "... exists in the variable value in the configuration file: CC_DENY = "SOMETHING_CC_DENY = \"value\"".
Sed is certainly the wrong tool for this:
#!/usr/bin/awk -f
BEGIN {
FS = OFS = "\42"
}
$2 = "AR,BE,CL,CN,CO,CS,ES,FR,GR,HK,IT,KO,PA,PE,PH,PL,RS,RU,SG,SK,TH,UA,VN," \
"AE,AF,AL,AS,AZ,BA,BD,BF,BH,BJ,BN,CI,DJ,EG,EH,ER,ET,GM,GN,GW,IQ,IR,IS,JO,KG," \
"KM,KW,KZ,LB,LY,MC,MK,ML,MR,MV,MY,NE,NG,OM,PK,PS,QA,SA,SD,SL,SN,SO,SY,TD,TJ," \
"TM,TN,TR,UZ,XK,YE,YT"

sed is ignoring quotation in a replacement string

I am trying to replace a string in a line with another string with quotation marks in a file, say, $FILE. I'm trying to use sed.
I want to replace m = uniform(0, 0, 1) by m.LoadFile("run2_initial_$NF.ovf")
I am using this:
sed -i 's#m = uniform(0, 0, 1)#m.LoadFile("run2_initial_$NF.ovf")#g' $FILE
What I am getting is m = uniform(0, 0, 1) replaced by m.LoadFile(run2_initial_$NF.ovf)
That is, sed is just ignoring the quotation marks in the replacement string.
Am I doing something stupid?
Please suggest.
Edit: The quotation mark is now working fine, when I try now. Though the $NF is not being replaced by a number :(
What I got in the new file is:
m.LoadFile("run2_initial_$NF.ovf")
whereas I wanted: m.LoadFile("run2_initial_3.ovf")
If you use double quotes, the variables inside the string will be replaced by their values, if you use single quotes, they won't.
What you need to do here is to replace the single quotes with double quotes, and escape the double quotes you already had:
$ echo "m = uniform(0, 0, 1)" | \
sed "s#m = uniform(0, 0, 1)#m.LoadFile(\"run2_initial_$NF.ovf\")#g"
m.LoadFile("run2_initial_3.ovf")

Trying to get sed to replace a filepath in a file with another filepath

This is my current code. I am trying to replace a filename string in the file with another filename. But I am currently getting the error
"sed: 1: "s/directory = "[A-Za-z0 ...": bad flag in substitute command: 'U'"
What is wrong with this code?
function restart_existing ()
{
old="directory = \"[A-Za-z0-9\/]\""
new="directory = \"$1\""
sed -i '' "s/$old/$new/" "$HOME/angelpretendconfig"
}
restart_existing "$HOME/blahblahblah/shoot/blah"
EDIT:
Thanks! I've adopted your advice, and adapted the code.
function restart_existing ()
{
old="directory = \"*\""
printf -v new 'directory = "%s"' "$1"
sed -i '' "s;$old;$new;" "$HOME/angelpretendconfig"
}
restart_existing "Query"
But now the line in question goes from
directory = "/home/jamie/bump/server"
directory = "Query"/home/jamie/bump/server"
Why does this occur?
Don't use forward slashes in sed when what you're replacing contains forward slashes:
$ sed 's;foo/bar;baz/wuz;' <<< "where is the foo/bar?"
where is the baz/wuz?
Also, sometimes it's more readable to avoid manually escaping quotes:
function restart_existing ()
{
old='directory = "[A-Za-z0-9\/]"'
printf -v new 'directory = "%s"' "$1"
sed -i '' "s;$old;$new;" "$HOME/angelpretendconfig"
}
restart_existing "$HOME/blahblahblah/shoot/blah"
$1 contains something, which is parsed as a special command to sed, in this case probably a / which marks the end of the replacement string, followed by some other characters.
You have to escape the replacement string first: Escape a string for a sed replace pattern.

sed single quotes

I've been banging into escaping single quote's problem using SED (Bash shell).
I need to make
$cfg['Servers'][$i]['password'] = '';
into
$cfg['Servers'][$i]['password'] = 'mypassword';
What I've tried is:
sed -i "s/$cfg['Servers'][$i]['password'] = '';/$cfg['Servers'][$i]['password'] = '$rootpassword';/g" /usr/share/phpmyadmin/libraries/config.default.bak
Which ends up really jumbling the line.
$cfg['Servers'][$i]['password['Servers'][]['passsword'] = 'mypassword'
I've tried the '\'' to escape single quotes and I think everything else under the sun but just can't get it quite there.
can anyone point to my probable obvious mistake?
Thank you.
instead of escaping, you can use \x27 for single quote. this works not only for sed, for awk etc. as well.
see test:
kent$ cat tt
$cfg['Servers'][$i]['password'] = ''
kent$ sed -r 's/(\$cfg\[\x27Servers\x27\]\[\$i\]\[\x27password\x27\] \= \x27)\x27/\1mypassword\x27/g' tt
$cfg['Servers'][$i]['password'] = 'mypassword'
note that, the sed line may not be the best solution for your problem, e.g. put the whole string to "s/../" may not be necessary. However, I just want to show how the \x27 worked.
$ sed -i "s/\$cfg\['Servers'\]\[\$i\]\['password'\] = '';/\$cfg['Servers'][\$i]['password'] = '\$rootpassword';/g" file
Try this:
sed -i "/Servers.*password.*''$/s/''/'foo'/" /path/to/your/testfile
Match a line that contains "anything..Servers..anything..password..anything..''" (end with '') and on that line replace '' with 'foo'
This can match more than one lines, but only the first occurance will be changed.
Test it, it's most probable that .. Servers .. password .. '' is only on one line.
Or you can just escape everything.

How do I strip the characters from this string?

"/home/chief/project/public/system/uploads/000/000/001/original/1/1.flv
to this:
/system/uploads/000/000/001/original/1/1.flv
str = "/home/chief/project/public/system/uploads/000/000/001/original/1/1.flv"
chopped = str.sub(/.*\/public/, "") #=> "/system/uploads/000/000/001/original/1/1.flv"
This will remove everything to the left of public (including /public). This way your code isn't specific to one location, but rather it is more portable in that you can have anything in front of /public, and it will still strip the characters.
s = "/home/chief/project/public/system/uploads/000/000/001/original/1/1.flv"
s.sub("/home/chief/project/public", "")
This should do the trick.
You should specify in which language.
Using sed is trivial.
echo "\"/home/chief/project/public/system/uploads/000/000/001/original/1/1.flv" | sed -e 's-\"/home/chief/project/public--'

Resources