New answers tagged quoting
9
An unquoted variable (as in $var) or command substitution (as in $(cmd) or `cmd`) is the split+glob operator in Bourne-like shells.
That is, their content is split according to the current value of the $IFS special variable (which by default contains the space, tab and newline characters)
And then each word resulting of that splitting is subject to ...
4
A quoted newline is a newline. So echo "$1" gives a single command line argument to echo, which then prints the newlines directly.
An unquoted newline is whitespace. So echo $1 gives many command line arguments to echo, which prints them one after another separated with spaces.
0
If you need newlines in your script many times you could declare a global variable holding a newline. That way you can use it in double-quoted strings (variable expansions).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
3
Use
eval ${VAR_NAME}='"${VAR_VALUE}"'
With eval, you get in general a two-fold expansion. If there are any things in an eval statement that should be expanded only once, it's usually better to quote them in such a way that the first expansion does nothing (except for quote removal) and the second expansion does the main job. In this concrete case, the ...
0
If sed is not a hard requirement, better use a dedicated tool instead.
If your file is valid XML (not just those 3 XML-looking tags), then you can use XMLStarlet:
xml ed -P -O -L \
-u '//username/text()' -v 'something' \
-u '//password/text()' -v 'somethingelse' \
-u '//dbname/text()' -v 'somethingdifferent' file.xml
The above will also work in ...
1
You need to quote \[.*^$/ in the regular expression part of the s command and \&/ in the replacement part, plus newlines. The regular expression is a basic regular expression, and in addition you need to quote the delimiter for the s command.
You can pick a different delimiter to avoid having to quote /. You'll have to quote that character instead, but ...
3
sed -e '/username/s/CDATA\[name\]/CDATA\[something\]/' \
-e '/password/s/CDATA\[password\]/CDATA\[somethingelse\]/' \
-e '/dbname/s/CDATA\[name\]/CDATA\[somethingdifferent\]/' file.txt
The /username/ before the s tells sed to only work on lines containing the string 'username'.
1
For replace the "name" word with the "something" word, use:
sed "s/\(<username><\!\[[A-Z]*\[\)name\]/\1something/g" file.xml
That is going to replace all the occurrences of the specified word.
So far all is outputted to standard output, you can use:
sed "s/\(<username><\!\[[A-Z]*\[\)name\]/\1something/g" file.xml > anotherfile.xml
...
2
sed -i -E "s/(<username>.+)name(.+<\/username>)/\1something\2/" file.xml
This is, I think, what you're looking for.
Explanation:
parenthesises in the first part define groups (strings in fact) that can be reused in the the second part
\1, \2, etc. in the second part are references to the i-th group captured in the first part (the numbering ...
4
Use "$@":
$ bar() { echo "$1:$2"; }
$ foo() { bar "$@"; }
$ foo "This is" a test
This is:a
"$@" and "$*" have special meanings:
"$@" expands to multiple words without performing expansions for the words (like "$1" "$2" ...).
"$*" joins positional parameters with the first character in IFS (or space if IFS is unset or nothing if IFS is empty).
3
You must use $@, instead of $*
bar() { echo $1:$2; }
foo() { bar "$@"; }
foo "This is" a test
ouput
This is:a
Why does it work?
Because with $*, all parameter is seen as a single word, it mean that you will pass This is a test to bar function. In this case, the 1st parameter pass to function bar is This, 2nd is is.
With $@, each parameter is a ...
3
! begins a shell history expansion. In particular, !foo expands to the last command you wrote that begins with foo. As you don't have any commands in your history that begin with restricted_area, bash is giving you an error. You can get around this by escaping or quoting the !:
7za ... -xr\!restr...
7za ... -xr'!'restr...
7za ... '-xr!restr...'
For more ...
3
By sh, I think you're refering to the Bourne shell which was the shell of most Unix systems before the mid 90s and was /bin/sh on Solaris prior to Solaris 11.
On Solaris 10 and older, don't use /bin/sh. That shell is from another era. Use /usr/xpg4/bin/sh instead.
In the Bourne shell ^ is an alias for | for compatibility with its predecessor the Thomson ...
1
I agree with l0b0 grep is a bad idea here but anyway, here is an explanation of the issue and a workaround. On Solaris 10 and older, /bin/sh is an antiquated shell that shouldn't be used for anything but running legacy scripts. You really should use ksh, bash or /usr/xpg4/bin/sh instead.
The root cause here is ^ used to be the original way to specify a pipe ...
2
You don't need ls and grep for this; you can use a simple glob /a/[0-9]*:
echo /a/[0-9]*
ls /a/[0-9]*
grep foo /a/[0-9]*
If you're using this in a script, beware that parsing ls output is a bad idea.
3
Something like this should work for you:
ls /a | egrep "^[0-9]"
Per @Anthons feedback egrep is deprecated, so you can use -E as a switch to the normal grep command instead:
ls /a | grep -E "^[0-9]"
Per @Stephane's feedback the extended regular expressions (ERE's) aren't even necessary in this situation. Really what matters is the quoting of the ^[0-9] ...
1
The echo Does not show you the whitespace at the end. For that you need something like echo "${URL_PARAMS}x". You can do set -x immediately before the wget call and set +x immediately after to see how wget is called.
The problem is the shell's word splitting:
${ARG_DATE/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/1} = "1"
instead of
...
2
There is a reason both single quotes ' and double quotes " exist. Parameters get expanded within double quotes but not within single quotes.
echo "<a href=\"/path/to/dir/$i\">$i</a>" >> /var/www/index.html
1
The problem is that you have single quotes wrapping the variables. You're variables are considered literals when wrapped by singled quotes. Try switching them to double quotes instead.
You also need to remove the back ticks around the "echo ...". Those exec a sub-shell which gives you this error:
a: line 5: <a ...
5
It seems that the problem is \( is interpreted by the shell first.
For example, you got a file in the current directory named:
foo(.test
Then
ls foo\(.text
and
ls "foo(.text"
both work.
So, the following works:
find . -regex ".*submit\(Web\)?\.m"
EDIT:
Single quote also works here.
Difference between single quote and double quote, see ...
Top 50 recent answers are included


