LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   sed command with exclamation mark (https://www.linuxquestions.org/questions/linux-newbie-8/sed-command-with-exclamation-mark-4175461277/)

sam_sung 05-09-2013 08:41 AM

sed command with exclamation mark
 
hey.. can anyone explain what this sed command doing in this script? i can't understand the exclamation marks in sed command. and another exclamation mark in the cat command line.

i had my brain faded understanding it. i didn't get any idea from anywhere. neither in man pages nor on the internet. please shed some light


Code:

if [ ! -d "${STEAM_DATA_HOME}/applications" ]; then
    mkdir -p "${STEAM_DATA_HOME}/applications"
fi
sed "s!/usr/bin/steam!${STEAM_DIR}/steam_on_debian.sh!" tree/usr/share/applications/steam.desktop > "${STEAM_DATA_HOME}/applications/steam.desktop"
cp -R tree/usr/share/icons "${STEAM_DATA_HOME}"


### Start: Code Block 3
echo "Adding Steam to PATH"
MAGIC_LINE="[[ -f \"${STEAM_DIR}/setup_debian_environment.sh\" ]] && source \"${STEAM_DIR}/setup_debian_environment.sh\""

cat > "${STEAM_DIR}/setup_debian_environment.sh" <<EOF
if ! which steam > /dev/null 2>&1; then
    PATH="${STEAM_DIR}/debian_bin:${PATH}"
    export PATH
fi


grail 05-09-2013 11:02 AM

Sed allows you to alter the delimiters used in case you have conflicting data being searched, ie. if you used the defaults (s///) you would need to escape all slashes in the string being
searched for and the string you are replacing. (see here for more info)

As for cat:
Code:

cat > "${STEAM_DIR}/setup_debian_environment.sh" <<EOF
I failed to see the exclamation mark in the above line of code?

shivaa 05-09-2013 11:20 AM

Quote:

Originally Posted by sam_sung (Post 4947874)
sed "s!/usr/bin/steam!${STEAM_DIR}/steam_on_debian.sh!" tree/usr/share/applications/steam.desktop > "${STEAM_DATA_HOME}/applications/steam.desktop"

Little tricky, but see here as well.
A ! character is used in sed to invert the restriction.

sam_sung 05-09-2013 11:20 AM

Quote:

Originally Posted by grail (Post 4947958)
Sed allows you to alter the delimiters used in case you have conflicting data being searched, ie. if you used the defaults (s///) you would need to escape all slashes in the string being
searched for and the string you are replacing. (see here for more info)

As for cat:
Code:

cat > "${STEAM_DIR}/setup_debian_environment.sh" <<EOF
I failed to see the exclamation mark in the above line of code?


thanx for the reply sir. i did not understand it fully as i am new to linux environment. sir, could you please provide any more examples please. sorry about the ambiguity of cat exclamation mark, what i meant was the ! in IF statement after that.

linosaurusroot 05-09-2013 11:25 AM

Quote:

Originally Posted by sam_sung (Post 4947972)
i meant was the ! in IF statement after that.


You can use a conditional block to execute only if some test is met:
Code:

if true
then
  echo The man from Finland says YES 
fi

and you can test for the opposite condition by putting ! between "if" and "true".

sam_sung 05-09-2013 11:42 AM

Quote:

Originally Posted by linosaurusroot (Post 4947977)
You can use a conditional block to execute only if some test is met:
Code:

if true
then
  echo The man from Finland says YES 
fi

and you can test for the opposite condition by putting ! between "if" and "true".

sorry again, i meant the following code

Code:

if ! which steam > /dev/null 2>&1; then
    PATH="${STEAM_DIR}/debian_bin:${PATH}"
    export PATH
fi


grail 05-09-2013 11:50 AM

linosaurusroot's post was an example but means the same in the code you are looking at. which is a command and the ! will negate its exit status based on the test of finding steam.

As for sed, did you read the link I gave you, it does provide other examples.

David the H. 05-10-2013 09:47 AM

We've got lots of things going on here. Let's try to break them down.

Let's start with sed.

1) When used with an address or address range, it means "not".

Code:

sed '10,/foo/!d infile
This will delete all lines except for the section starting with line 10 and ending with the next line that contains "foo".

2) It can be used as a delimiter in the 's' substitution, as mentioned. But any simple ascii character can be used, not just '!'. The command will simply use the first character after 's' as the delimiter.

These are all the same:
Code:

sed 's/foo/bar/' infile
sed 's!foo!bar!' infile
sed 's_foo_bar_' infile
sed 's@foo@bar@' infile

The address range regex field can be changed too, but you have to precede the delimiter with a backslash.

Code:

sed '10,\!foo!!d infile
Now, in the shell...

Among other uses, adding a '!' in front of a command reverses the exit code. A successful 0 exit code will become 1, and a non-zero exit code becomes 0.

Code:

ls non-existing-file ; echo $?
2
! ls non-existing-file ; echo $?
0

So naturally, when used in a loop or if test, it means that the sub-command runs if the command fails.


All times are GMT -5. The time now is 08:46 AM.