how to create a regex string where you don't know what to escape











up vote
2
down vote

favorite












I have a passwd file with the line containing root being:



root:6UZSjeWUui3JQ:0:0:root:/root:/bin/sh


I want this line to be changed to:



root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:root:/root:/bin/sh


This password generated using:



hash=$(openssl passwd -1 -salt $salt angus)


which has an embedded / character. So this means I cannot use this sed:



sed -e "s/root:.*:0:0:/root:$hash:0:0:/" './test/etc/passwd'


I have to change to:



sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


otherwise I get this cryptic error:



sed -e expression #1, char 32: unknown option to `s'


But what if the hash generated has an embedded | character? How would I make this script robust to handle any hash?



Here is my script at present which will fail if a hash has an embedded | character.



eg if call like this:



sudo ./justsed.sh angus dog


Script:



#!/bin/bash

if [[ ! $1 || ! $2 ]]; then
echo "Usage: justsed.sh <password> <salt>"
exit 0
fi

# change salt to random chars for real use
salt=$2

# example: $1$dog$cNv/OuAd7CMNdrhWsHXAR.
hash=$(openssl passwd -1 -salt $salt $1)

printf "using the following hash: %s, updating file: %sn" $hash "./test/etc/passwd"

echo "sed command with escaped /"
# this line works
sed -e 's/root:.*:0:0:/root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:/' './test/etc/passwd'

echo "sed replace text"
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'









share|improve this question






















  • Duplicate on U&L: How to ensure that string interpolated into sed substitution escapes all metachars
    – RoVo
    Dec 3 at 12:47

















up vote
2
down vote

favorite












I have a passwd file with the line containing root being:



root:6UZSjeWUui3JQ:0:0:root:/root:/bin/sh


I want this line to be changed to:



root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:root:/root:/bin/sh


This password generated using:



hash=$(openssl passwd -1 -salt $salt angus)


which has an embedded / character. So this means I cannot use this sed:



sed -e "s/root:.*:0:0:/root:$hash:0:0:/" './test/etc/passwd'


I have to change to:



sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


otherwise I get this cryptic error:



sed -e expression #1, char 32: unknown option to `s'


But what if the hash generated has an embedded | character? How would I make this script robust to handle any hash?



Here is my script at present which will fail if a hash has an embedded | character.



eg if call like this:



sudo ./justsed.sh angus dog


Script:



#!/bin/bash

if [[ ! $1 || ! $2 ]]; then
echo "Usage: justsed.sh <password> <salt>"
exit 0
fi

# change salt to random chars for real use
salt=$2

# example: $1$dog$cNv/OuAd7CMNdrhWsHXAR.
hash=$(openssl passwd -1 -salt $salt $1)

printf "using the following hash: %s, updating file: %sn" $hash "./test/etc/passwd"

echo "sed command with escaped /"
# this line works
sed -e 's/root:.*:0:0:/root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:/' './test/etc/passwd'

echo "sed replace text"
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'









share|improve this question






















  • Duplicate on U&L: How to ensure that string interpolated into sed substitution escapes all metachars
    – RoVo
    Dec 3 at 12:47















up vote
2
down vote

favorite









up vote
2
down vote

favorite











I have a passwd file with the line containing root being:



root:6UZSjeWUui3JQ:0:0:root:/root:/bin/sh


I want this line to be changed to:



root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:root:/root:/bin/sh


This password generated using:



hash=$(openssl passwd -1 -salt $salt angus)


which has an embedded / character. So this means I cannot use this sed:



sed -e "s/root:.*:0:0:/root:$hash:0:0:/" './test/etc/passwd'


I have to change to:



sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


otherwise I get this cryptic error:



sed -e expression #1, char 32: unknown option to `s'


But what if the hash generated has an embedded | character? How would I make this script robust to handle any hash?



Here is my script at present which will fail if a hash has an embedded | character.



eg if call like this:



sudo ./justsed.sh angus dog


Script:



#!/bin/bash

if [[ ! $1 || ! $2 ]]; then
echo "Usage: justsed.sh <password> <salt>"
exit 0
fi

# change salt to random chars for real use
salt=$2

# example: $1$dog$cNv/OuAd7CMNdrhWsHXAR.
hash=$(openssl passwd -1 -salt $salt $1)

printf "using the following hash: %s, updating file: %sn" $hash "./test/etc/passwd"

echo "sed command with escaped /"
# this line works
sed -e 's/root:.*:0:0:/root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:/' './test/etc/passwd'

echo "sed replace text"
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'









share|improve this question













I have a passwd file with the line containing root being:



root:6UZSjeWUui3JQ:0:0:root:/root:/bin/sh


I want this line to be changed to:



root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:root:/root:/bin/sh


This password generated using:



hash=$(openssl passwd -1 -salt $salt angus)


which has an embedded / character. So this means I cannot use this sed:



sed -e "s/root:.*:0:0:/root:$hash:0:0:/" './test/etc/passwd'


I have to change to:



sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


otherwise I get this cryptic error:



sed -e expression #1, char 32: unknown option to `s'


But what if the hash generated has an embedded | character? How would I make this script robust to handle any hash?



Here is my script at present which will fail if a hash has an embedded | character.



eg if call like this:



sudo ./justsed.sh angus dog


Script:



#!/bin/bash

if [[ ! $1 || ! $2 ]]; then
echo "Usage: justsed.sh <password> <salt>"
exit 0
fi

# change salt to random chars for real use
salt=$2

# example: $1$dog$cNv/OuAd7CMNdrhWsHXAR.
hash=$(openssl passwd -1 -salt $salt $1)

printf "using the following hash: %s, updating file: %sn" $hash "./test/etc/passwd"

echo "sed command with escaped /"
# this line works
sed -e 's/root:.*:0:0:/root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:/' './test/etc/passwd'

echo "sed replace text"
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'






command-line bash scripts sed regex






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 3 at 11:07









arcomber

14115




14115












  • Duplicate on U&L: How to ensure that string interpolated into sed substitution escapes all metachars
    – RoVo
    Dec 3 at 12:47




















  • Duplicate on U&L: How to ensure that string interpolated into sed substitution escapes all metachars
    – RoVo
    Dec 3 at 12:47


















Duplicate on U&L: How to ensure that string interpolated into sed substitution escapes all metachars
– RoVo
Dec 3 at 12:47






Duplicate on U&L: How to ensure that string interpolated into sed substitution escapes all metachars
– RoVo
Dec 3 at 12:47












1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










Just escape it before calling sed:



hash=$(openssl passwd -1 -salt $salt $1 | sed 's|/|\/|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


But that will break if your hash contains ", or , as well as if it contains & since sed will read that as "whatever was matched" when the & is present on the right hand side of the substitution operator. So you'll need to escape those as well:



hash=$(openssl passwd -1 -salt $salt $1 | sed -E 's|(["/@])|\1|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


Finally, if your hash contains : that will break the whole thing since that can't be escaped given that it's a separator in the passwd file. So I would add a test for that:



if [[ "$hash" =~ /:/ ]];
then
echo "Invalid password! Choose another"
exit
fi





share|improve this answer























  • How would I test this with an embedded | or "
    – arcomber
    Dec 3 at 12:09










  • @arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
    – terdon
    Dec 3 at 12:19










  • and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
    – RoVo
    Dec 3 at 12:42












  • @RoVo good point about `, thanks. But why escape the &`?
    – terdon
    Dec 3 at 12:58










  • & is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
    – RoVo
    Dec 3 at 13:55













Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1098114%2fhow-to-create-a-regex-string-where-you-dont-know-what-to-escape%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










Just escape it before calling sed:



hash=$(openssl passwd -1 -salt $salt $1 | sed 's|/|\/|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


But that will break if your hash contains ", or , as well as if it contains & since sed will read that as "whatever was matched" when the & is present on the right hand side of the substitution operator. So you'll need to escape those as well:



hash=$(openssl passwd -1 -salt $salt $1 | sed -E 's|(["/@])|\1|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


Finally, if your hash contains : that will break the whole thing since that can't be escaped given that it's a separator in the passwd file. So I would add a test for that:



if [[ "$hash" =~ /:/ ]];
then
echo "Invalid password! Choose another"
exit
fi





share|improve this answer























  • How would I test this with an embedded | or "
    – arcomber
    Dec 3 at 12:09










  • @arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
    – terdon
    Dec 3 at 12:19










  • and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
    – RoVo
    Dec 3 at 12:42












  • @RoVo good point about `, thanks. But why escape the &`?
    – terdon
    Dec 3 at 12:58










  • & is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
    – RoVo
    Dec 3 at 13:55

















up vote
2
down vote



accepted










Just escape it before calling sed:



hash=$(openssl passwd -1 -salt $salt $1 | sed 's|/|\/|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


But that will break if your hash contains ", or , as well as if it contains & since sed will read that as "whatever was matched" when the & is present on the right hand side of the substitution operator. So you'll need to escape those as well:



hash=$(openssl passwd -1 -salt $salt $1 | sed -E 's|(["/@])|\1|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


Finally, if your hash contains : that will break the whole thing since that can't be escaped given that it's a separator in the passwd file. So I would add a test for that:



if [[ "$hash" =~ /:/ ]];
then
echo "Invalid password! Choose another"
exit
fi





share|improve this answer























  • How would I test this with an embedded | or "
    – arcomber
    Dec 3 at 12:09










  • @arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
    – terdon
    Dec 3 at 12:19










  • and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
    – RoVo
    Dec 3 at 12:42












  • @RoVo good point about `, thanks. But why escape the &`?
    – terdon
    Dec 3 at 12:58










  • & is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
    – RoVo
    Dec 3 at 13:55















up vote
2
down vote



accepted







up vote
2
down vote



accepted






Just escape it before calling sed:



hash=$(openssl passwd -1 -salt $salt $1 | sed 's|/|\/|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


But that will break if your hash contains ", or , as well as if it contains & since sed will read that as "whatever was matched" when the & is present on the right hand side of the substitution operator. So you'll need to escape those as well:



hash=$(openssl passwd -1 -salt $salt $1 | sed -E 's|(["/@])|\1|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


Finally, if your hash contains : that will break the whole thing since that can't be escaped given that it's a separator in the passwd file. So I would add a test for that:



if [[ "$hash" =~ /:/ ]];
then
echo "Invalid password! Choose another"
exit
fi





share|improve this answer














Just escape it before calling sed:



hash=$(openssl passwd -1 -salt $salt $1 | sed 's|/|\/|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


But that will break if your hash contains ", or , as well as if it contains & since sed will read that as "whatever was matched" when the & is present on the right hand side of the substitution operator. So you'll need to escape those as well:



hash=$(openssl passwd -1 -salt $salt $1 | sed -E 's|(["/@])|\1|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'


Finally, if your hash contains : that will break the whole thing since that can't be escaped given that it's a separator in the passwd file. So I would add a test for that:



if [[ "$hash" =~ /:/ ]];
then
echo "Invalid password! Choose another"
exit
fi






share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 3 at 13:57

























answered Dec 3 at 11:34









terdon

63.9k12135212




63.9k12135212












  • How would I test this with an embedded | or "
    – arcomber
    Dec 3 at 12:09










  • @arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
    – terdon
    Dec 3 at 12:19










  • and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
    – RoVo
    Dec 3 at 12:42












  • @RoVo good point about `, thanks. But why escape the &`?
    – terdon
    Dec 3 at 12:58










  • & is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
    – RoVo
    Dec 3 at 13:55




















  • How would I test this with an embedded | or "
    – arcomber
    Dec 3 at 12:09










  • @arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
    – terdon
    Dec 3 at 12:19










  • and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
    – RoVo
    Dec 3 at 12:42












  • @RoVo good point about `, thanks. But why escape the &`?
    – terdon
    Dec 3 at 12:58










  • & is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
    – RoVo
    Dec 3 at 13:55


















How would I test this with an embedded | or "
– arcomber
Dec 3 at 12:09




How would I test this with an embedded | or "
– arcomber
Dec 3 at 12:09












@arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
– terdon
Dec 3 at 12:19




@arcomber what do you mean? Just use a string: hash=$(echo '$1$do"g$cNv/OuAd7CMNdrhWsHXAR' | sed -E 's|(["/])|\1|g').
– terdon
Dec 3 at 12:19












and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
– RoVo
Dec 3 at 12:42






and you need to escape & and also . (e.g. n will break the s/// command, or if you have as last char, it will cause issues obviously).
– RoVo
Dec 3 at 12:42














@RoVo good point about `, thanks. But why escape the &`?
– terdon
Dec 3 at 12:58




@RoVo good point about `, thanks. But why escape the &`?
– terdon
Dec 3 at 12:58












& is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
– RoVo
Dec 3 at 13:55






& is the whole match (like ). ==> echo "foo" | sed "s/.*/&bar/" gives foobar.
– RoVo
Dec 3 at 13:55




















draft saved

draft discarded




















































Thanks for contributing an answer to Ask Ubuntu!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1098114%2fhow-to-create-a-regex-string-where-you-dont-know-what-to-escape%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

Mangá

Eduardo VII do Reino Unido