Tag Info

Hot answers tagged

13

The tutorial is wrong. POSIX says: A single-quote cannot occur within single-quotes. Here's some alternatives: echo $'It\'s Shell Programming' # ksh, bash, and zsh only, does not expand variables echo "It's Shell Programming" # all shells, expands variables echo 'It'\''s Shell Programming' # all shells, single quote is outside the quotes echo ...


8

You need to quote the variables and avoid the command substitution: for i in ./*.mkv; do ffmpeg -i "${i}" -vcodec copy -acodec copy "${i}.mp4"; done See When is double-quoting necessary? for a detailed explanation of quoting. While I'm at it, the above produces files with a .mkv.mp4 extension; to fix that: for i in ./*.mkv; do ffmpeg -i "${i}" -vcodec ...


6

If you want to search for the regexp that is the concatenation of the arguments with space characters in between, that would be: #! /bin/sh - IFS=' ' # used for "$*" grep -r --color=always -e "$*" . | nolong "$*" joins the positional parameters with the first character (actually byte except with yash) of $IFS. Note (as you seem to be confused by the ...


5

You need to escape the quotes in the echo command to see them in the output, but you shouldn't escape them in the actual command: #!/bin/bash echo ./yowsup/yowsup-cli demos --s $1 \"$2\" -c yowsup/config & ./yowsup/yowsup-cli demos --s $1 "$2" -c yowsup/config & The quotes are used in the actual command to prevent splitting of $2 - which contains ...


5

Use something like this perhaps (if gnu grep). grep -r 'content pattern' --include==*.cpp man grep --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude) Also see the options for null delimiters. -Z, --null Output a zero byte (the ASCII NUL character) instead of the character that ...


3

Since you have been using double quotes, any $-variables will be expanded by bash before they reach awk. That's the first problem: { print $1, $3 } will expand to { print , }. Next, the awk syntax you are trying to use is /<regular expression>/ { <action> }: the regular expression is not allowed to contain any unquoted slashes, but $PWD ...


3

The first issue is that $directory contains slashes which are also being used as the delimiter for the substitution operator (s///). Basically, if $directory is /home/je_b, what Perl sees is: perl -i -pe "s/foo//home/jb/ if \$. == 4" file.txt It takes the / of /home as the second / of the s/// operator. The simplest solution is to use a different ...


3

In the following lines, workspace="~/GIT_Workspace/my_project/" filename="~/GIT_Workspace/Back/$timestamp-$branch.tar.gz" ~ is not getting expanded to your home directory because it's inside quotes. It needs to be outside of quotes in order to get expanded. So your script is trying to open a file that begins with a literal ~ character, which of course ...


2

The problem was that since the su statement was in double quotes, the variables were all expanded before the su command was called, which means $var becomes "cat" but $i becomes "" since it was not defined. Bash doesn't know that it was supposed to be an iterator variable, it just expands it to a NULL string. The answer is to escape that "$" like so: ...


2

In the example you mention, where the expansion for the alias is single word containing no character that is subject to expansion, it makes no difference how you quote the name _cutf: $ alias cutf="_cutf" $ alias cutf alias cutf='_cutf' $ unalias cutf $ alias cutf='_cutf' $ alias cutf alias cutf='_cutf' $ unalias cutf $ alias cutf=_cutf $ alias cutf alias ...


2

If you don't have a file in the current directory whose name starts with a backslash, this is expected behaviour. Bash expands * to match any existing file names, but: If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged. Because there was no filename starting with \, the pattern was left as-is ...


2

You can use the wildcard * for the name that you don't know. Let's say you set FILE=../"$1"/*.txt Wildcard expansion only happens outside of quotes. $FILE variable still has the asterisk in it. So, [ -f "$FILE" ] is equivalent to [ -f "../test/*.txt" ] which wants a literal asterisk in the filename, but [ -f $FILE ] is equivalent to [ -f ...


2

If you have to jump through alot of hoops, then the efficiency of xargs is lost anyway. Here is one crude work around: find . -iname "*.cpp" | grep "<pattern>" | while read -r x; do grep exa "$x"; done Every time I run into problems with spaces in file names, the answer is double quotes on a variable.


2

This should work even without GNU tools: #Find all C++ files that match a certain pattern and then search them find . -name "*.cpp" \ | grep "<name regex>" \ | perl -pne 's/\n/\0/' \ | xargs -0 grep "<content regex>" The perl call replaces line breaks with null characters, which will allow xargs -0 to interpret the input on a per-line ...


2

You need to escape dot in search pattern: sed -i 's/1\.0/2.0/g' /home/user1/file1.txt


2

I think it's best understood by the output of echo $(echo '\\') (i.e. a variant without the outer quotes), which results in \\. The point is that there's no literal string interpretation of the backslash(es) when the command substitution entity $(...) is expanded. (This is similar in case you have escape characters stored in strings; there won't be a ...


2

That cannot work. When your shell performs word splitting, you will have four arguments: sh -c 'echo "a"' To accomplish this, you must use a bash array: cmd=( sh -c 'echo "a"' ) "${cmd[@]}"


2

In a command substitution delimited with $(…), what's inside the parentheses is parsed in the same way as a toplevel command (except in a few corner cases involving unbalanced closing parentheses). What's inside the parentheses is an ordinary shell snippet, there's no additional backslash expansion being done. The command echo '\\' prints three characters: ...


1

It has more to do with quoting, $ echo '\' \ $ echo '\\' \\ $ echo "\\" \ With single quotes, whatever is there between quotes is echoed. With double quotes, the shell looks inside and does processing.


1

Use find to do all the filename filtering.  Rather than find . -name "*.cpp" | grep "foo" | xargs grep … do find . -name "*.cpp" -name "*foo*" -print0 | xargs -0 grep … If you want to do something slightly more complicated, like find . -name "*.cpp" | egrep "foo|bar" | xargs grep … you can do find . -name "*.cpp" "(" -name "*foo*" -o -name "*bar*" ...


1

I think what you're trying to ask is how to mix and match variables that much be evaluated locally with those that need to be evaluated remotely. One option is to write a script for the actions to be handled remotely, thus encapsulating any reference to local variables so that the local host's quotes can't see them to expand them. Another option for a ...


1

You can see for yourself: [user@bluepc ~]$ echo "$HOSTNAME;" bluepc; [user@bluepc ~]$ echo '$HOSTNAME;' $HOSTNAME; Environment variables within single quotes are treated as strings. In the case of ssh, if you use double quotes: The string is substituted at local server. The command is executed remotely. if you use single quotes: The string is ...


1

how about for filepath in "$1/"*.flac do ffmpeg -i "${file_path}" -f ... where "$1/"*.flac will garantee .flac suffix in the end be sure to quote "${file_path}" basename can be found using bn=$(basename "${file_path}") un flac'ed basename can be found using bnnf=$(basename "${file_path}" .flac) sample A > ls -l Music total 0 -rw-rw-r-- ...


1

Try single quotes: wget 'http://xxxx/Sankarea - 6 - It`s Because I... Ran Into You (720p-100MB)[Commie][Daylighter].mkv' and if you would have a single quote in the URL itself then split the URL in two strings and insert the single quote with a backslash: '...'\''....' or using double quotes: '...'"'"'....'. Leave no spaces between these strings. $ echo ...


1

You need to quote the argument when your script is called to show that it is one argument and not two independent arguments. Inside your script you then have to use "$@". grep -r --color=always "$@" . | nolong And the call is (for example)... findstr "hello world" (But note that the grep pattern uses just one argument, so "$1" instead of "$@" would ...


1

try this: Escape all . by replacIng all . to \. str1="$( echo -n $i | sed 's/\./\\\./g' )" repeat same for str2 using $j . then replace as follows sed "s/$str1/$str2/g"


1

You can just use sed to do the fixup for you: printf '%s\n' "$i" "$j" | sed 's/[]\$*&/.^[]/\\&/g;H;$!d x;y|\n|/|;s|.*|s&/g|' | sed -f - /path/to/infile So this s///ubstitution will escape any/all BRE metacharacters in input: s/[]\$*&/.^[]/\\&/g ...by prefixing each with a backslash. The first sed then saves a copy of the first ...


1

Here is escaped command: alias mm='ps -u $USER -o pid,rss,command | \ awk '\''{print $0}{sum+=$2} END {print "Total", sum/1024, "MB"}'\' Example of escaping quotes in shell: $ echo 'abc'\''abc' abc'abc $ echo "abc"\""abc" abc"abc It's simply done by finishing already opened one ('), placing escaped one (\'), then opening another one ('). ...


1

It's just that simple - if there's no variable, the brackets are interchangeable. Shell script, while very useful, is also a very simple language. I (and some others I know) tend to use double quotes by default, just from force of habit - and I have never run into issues.


1

The special parameter ${array[@]} in double quotes causes word splitting if the array has more than one member: $ for word in "for i in ${arr[@]} ; do" ; do echo "$word" ; done for i in a b c ; do If your modules' names don't contain spaces, you can have more luck using the * subscript: $ for word in "for i in ${arr[*]} ; do" ; do echo "$word" ; done for ...



Only top voted, non community-wiki answers of a minimum length are eligible