The alias below works well in zsh when spaces in directory names are \ escaped, but bash doesn't handle them properly. What changes would be required to make them work with bash properly.    dum() {   du -h --max-depth=1 $1   }   zsh succeeds   user@server: dum "Server Configuration" 32K     Server Configuration  user@server: dum Server\ Configuration 32K     Server Configuration   bash fails  user@server:~$ dum "Server Configuration" 8.0K    Server/install_scripts 300K    Server du: cannot access 'Configuration': No such file or directory user@server:~$ dum Server\ Configuration/ 8.0K    Server/install_scripts 300K    Server du: cannot access 'Configuration/': No such file or directory         How can the alias be written to make it work in bash?
9335
The old advice used to be to double-quote any expression involving a $VARIABLE, at least if one wanted it to be interpreted by the shell as one single item, otherwise, any spaces in the content of $VARIABLE would throw off the shell.  I understand, however, that in more recent versions of shells, double-quoting is no longer always needed (at least for the purpose described above).  For instance, in bash:  % FOO='bar baz' % [ $FOO = 'bar baz' ] &amp;&amp; echo OK bash: [: too many arguments % [[ $FOO = 'bar baz' ]] &amp;&amp; echo OK OK % touch 'bar baz' % ls $FOO ls: cannot access bar: No such file or directory ls: cannot access baz: No such file or directory   In zsh, on the other hand, the same three commands succeed.  Therefore, based on this experiment, it seems that, in bash, one can omit the double quotes inside [[ ... ]], but not inside [ ... ] nor in command-line arguments, whereas, in zsh, the double quotes may be omitted in all these cases.  But inferring general rules from anecdotal examples like the above is a chancy proposition.  It would be nice to see a summary of when double-quoting is necessary.  I'm primarily interested in zsh, bash, and /bin/sh.
75076
Following on from  about stripping newlines out of text, I want to turn this into a zsh alias as follows:  alias striplines=' awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'   I've tried escaping the quotes inside the awk script, but I'm getting this error:  awk: (FILENAME=bspsrobustness FNR=1) fatal: division by zero attempted   (The file is called bspsrobustness)  Is there a way to do what I want? I suppose I could turn this into an awk script rather than a zsh alias, is that my best option?
8187
Writing my first script so I'm sure this is a basic question, but can someone please explain to me why I can:  cd ~ cd bin cd ~/bin cd 'bin'   But not  cd '~' cd '~/bin'   I need to cd to a directory path with a space in one of the directory names, so I need the quotes (it's Windows Program Files under wine). I can get around it with two cd commands, but why can't I put ~ in quotes?  If I type cd '~' (or cd "~") I get:  bash: cd: ~: No such file or directory
2796
Ok, I have a bunch of files starting with a dash, -. Which is not so good... and I want to rename them. In my particular case I would just like to put a character in front of them.  I found the following line that should work, but because of it dash it doesn't:  for file in -N*.ext; do mv $file x$file; done   If I put an echo in front of the mv I get a bunch of  mv -N1.ext x-f1.ext mv -N2.ext x-f2.ext   Which is correct, except of course it will think the first filename is options. So when I remove the echo and run it I just get a bunch of  mv: illegal option -- N   I have tried to change it to  for file in -N*.ext; do mv "$file" "x$file"; done   but the quotes are just ignored it seems. Tried to use single quotes, but then the variable wasn't expanded... What do I do here?  Update: I have now also tried to quote the quotes. Like this:  for file in -N*.ext; do mv '"'$file'"' '"'x$file'"'; done   And when I echo that, it looks correct, but when I actually run it I just get  mv: rename "-N1.ext" to "x-n1.ext":: No such file or directory   I have just no clue how to do this now... sigh
36541
I just noticed that on one of my machines (running Debian Sid) whenever I type ls any file name with spaces has single quotes surrounding it. I immediately checked my aliases, only to find them intact. wyatt@debian630:~/testdir$ ls 'test 1.txt'  test1.txt wyatt@debian630:~/testdir$ alias alias ls='ls --color=auto' alias wget='wget --content-disposition' wyatt@debian630:~/testdir$   Another test, with files containing single quotes in their names (also answering a request by jimmij): wyatt@debian630:~/testdir$ ls 'test 1.txt'  test1.txt  'thishasasinglequotehere'\''.txt' wyatt@debian630:~/testdir$ touch &quot;'test 1.txt'&quot; wyatt@debian630:~/testdir$ ls ''\''test 1.txt'\'''  test1.txt 'test 1.txt'          'thishasasinglequotehere'\''.txt'   update with new coreutils-8.26 output (which is admittedly much less confusing, but still irritating to have by default). Thanks to Pádraig Brady for this printout: $ ls &quot;'test 1.txt'&quot;   test1.txt 'test 1.txt'    &quot;thishasasinglequotehere'.txt&quot;  $ ls -N 'test 1.txt'  test1.txt test 1.txt    thishasasinglequotehere'.txt  Why is this happening? How do I stop it properly? To be clear, I myself set ls to automatically color output. It just never put quotes around things before. I'm running bash and coreutils 8.25. Any way to fix this without a recompile? EDIT: Appears the coreutils developers  to break with the convention and make this the global default.  UPDATE - October 2017 - Debian Sid has re-enabled the shell escape quoting by default.  And at the bottom of the reply chain to the previous bug report, &quot;the change was intentional and will remain.&quot;  I thought this had already been settled, but apparently it was just reverted so that the &quot;stable&quot; Debian branch could keep its &quot;feature freeze&quot; while getting the other fixes, etc. from the newer version. So that's a shame (in my opinion). UPDATE: April 2019: Just found a  that was caused by this change to ls. When you're confusing developers and generating false bug reports, I think it might be time to re-evaluate your changes. Update: Android toybox ls is now doing something similar to this but with backslashes instead of quotes. Using the -q option makes spaces render as 'question mark characters' (I have not checked what they are, since they're obviously not spaces), so the only fix I have found so far without rooting the device in question is to add this to a script and source it when launching a shell. This function makes ls use columns if in a terminal and otherwise print one-per-line, while tricking ls into printing spaces verbatim because it's running through a pipe. ls() {     # only way I can stop ls from escaping with backslashes     if [ -t 1 ]; then         /system/bin/ls -C $@ |cat     else         /system/bin/ls $@ |cat     fi }
33154
I have this folder structure:  ├── foo1 │   ├── bar1.txt │   └── bar2.txt ├── foo2 │   ├── bar3.txt │   └── bar4 with a space.txt └── foo3     └── qux1         ├── bar5.txt         └── bar6.txt   that I would like to flatten into this, with an underscore between each folder level:  ├── foo1_bar1.txt ├── foo1_bar2.txt ├── foo2_bar3.txt ├── foo2_bar4 with a space.txt ├── foo3_qux1.bar6.txt └── foo3_qux1_bar5.txt   I've looked around and I haven't found any solution that work, mostly I think because my problem has two particularities: there might be more than one folder level inside the root one and also because some files might have spaces.  Any idea how to accomplish this in bash? Thanks!  Edit: Running gleen jackman proposed answer I get this:    There are two underscores for the first level folder. Any idea how to either avoid this or just rename it so that is just one underscore? Thanks.
23932
I'm on a Mac and the cp and mv commands are killing me due to them copying the contents of a directory if a trailing slash is present. It has bitten me more than once when I use tab completion to specify the directory I want to copy.  I have noticed zsh has a neat feature that removes the trailing slash if it's not needed after a space or enter key is pressed. Is there any way to have bash mimic this behavior?
100841
I'm using the command  ls -a | grep '^\.'  for showing only the hidden files. I added the line  alias hidden='ls -a | grep '^\.'' # show only hidden files  to .bash_aliases file  but this does not work. It's probably the problem with ' character.  Could you please help me write the correct alias?
51790
I have a bash shell script that loops through all child directories (but not files) of a certain directory.  The problem is that some of the directory names contain spaces.    Here are the contents of my test directory:  $ls -F test Baltimore/  Cherry Hill/  Edison/  New York City/  Philadelphia/  cities.txt   And the code that loops through the directories:  for f in `find test/* -type d`; do   echo $f done   Here's the output:   test/Baltimore test/Cherry Hill test/Edison  test/New York City test/Philadelphia   Cherry Hill and New York City are treated as 2 or 3 separate entries.  I tried quoting the filenames, like so:  for f in `find test/* -type d | sed -e 's/^/\"/' | sed -e 's/$/\"/'`; do   echo $f done   but to no avail.  There's got to be a simple way to do this.    The answers below are great.  But to make this more complicated - I don't always want to use the directories listed in my test directory.  Sometimes I want to pass in the directory names as command-line parameters instead.  I took Charles' suggestion of setting the IFS and came up with the following:  dirlist="${@}" (   [[ -z "$dirlist" ]] &amp;&amp; dirlist=`find test -mindepth 1 -type d` &amp;&amp; IFS=$'\n'   for d in $dirlist; do     echo $d   done )   and this works just fine unless there are spaces in the command line arguments (even if those arguments are quoted).  For example, calling the script like this: test.sh "Cherry Hill" "New York City" produces the following output:   Cherry Hill New York City
36164
According to  and my own understanding, the tilde expands to the home directory:  $ echo ~ /home/braiam   Now, whenever I want the shell expansion to work, i. e. using variable names such $FOO, and do not break due unexpected characters, such spaces, etc. one should use double quotes ":  $ FOO="some string with spaces" $ BAR="echo $FOO" $ echo $BAR echo some string with spaces   Why doesn't this expansion works with the tilde?  $ echo ~/some/path /home/braiam/some/path $ echo "~/some/path" ~/some/path
2861
I wrote the following script to diff the outputs of two directores with all the same files in them as such:  #!/bin/bash  for file in `find . -name "*.csv"`   do      echo "file = $file";      diff $file /some/other/path/$file;      read char; done   I know there are other ways to achieve this.  Curiously though, this script fails when the files have spaces in them.  How can I deal with this?  Example output of find:  ./zQuery - abc - Do Not Prompt for Date.csv
67504
I've written a bash script which should cd me to a directory.   My problem is that only the directory in the subshell changes.  I've read of many similar problems to this, but I want to know if there is a solution besides using an alias, a function or sourcing the script.  If you don't understand what I mean, here's an example:  user@linux ~: cat ./myscript.sh #!/bin/bash cd /any/directory user@linux ~: ./myscript.sh user@linux ~:    Please note that my script is much longer, so I don't want to use a function!
5412
Running a kornshell and trying to traverse a directory tree. Want to cd to a sub-directory named as follows:   -3ab_&amp;_-3dc.img   My question is HOW do I need to escape the ampersand in this name? I've tried different combinations of double-quotes and backslashes without success.
72600
Recently it seems that shell has changed how it handles spaces in parameters. It used to handle them properly (Or at least as I intended it to), but now it recognises it as a bunch of different parameters and completely misses the escape character.  An example of a small script that used to work very well:  #!/bin/sh  exec /home/evan/.applications/Sublime\ Text\ 2/sublime_text $1   So I would give it some filepath with spaces and it used to open the proper file eg, /home/evan/Document/My\ File\ Path/file.txt would open that file.txt. Now it opens "My", "File", "Path", and some unknown "file.txt" Obviously, that won't be the file.txt that I am looking for.  Any help would be appreciated. Thank you in advance.  OS: Ubuntu 13.04 GNOME edition with latest updates  EDIT: I forgot to mention that the command executes perfect. The parameter does not.
16972
I'm working on a python script that passes file locations to an scp subprocess. That's all fine, but I'm in a situation where I may end up concatenating a path with a filename such that there's a double '/ in the path. I know that bash doesn't care if you have multiple file separators, but I'm wondering how exactly that is rectified. Is it bash that strips extra /s or does it really not matter ever?  I ask because it will save me several lines of code to check for extra /s while concatenating. I know it's not a big deal, but I'm curious as well. I have a bash script that has the line cd //usr (instead of cd /usr), which seems to imply there might be a significance to using multiple /s in a path
4911
I started learning linux on vmware using centos 7. I created an image directory and several layers of files and sub-directories in that folder. most of the names containing spaces. I want to use a single command to rename all the files and directories at once.   command i am using right now is  find . -type f -exec rename "find" "replace" {} \; &amp; find . -type d -exec rename "find" "replace" {} \; Where as find is a space and replace is "-"(hiphen). I even tried below command looking at one of the answer in stack exchange.  find . -iname "find" -exec rename "find" "replace" {} \;
112882
Something like the following is what I what I'm after,  but my code doesn't work, no matter how I escape {} and + ;     find ./ -maxdepth 1 -type d -name '.*' -exec \     find {} -maxdepth 1 -type f -name '*.ini' -exec \         md5sum \{\} \\; \;   After seeing this ,  I found that the following code works, but it isn't nesting find as such, and I suspect there is a better way to do this particular job.       find ./ -maxdepth 1 -type d -name '.*' \ -exec bash -c 'for x; do     find "$x" -maxdepth 1 -type f -name "*.ini" \     -exec md5sum \{\} \;; \ done' _ {} \+   Is there some way to nest find -exec without the need to invoke  a shell (as above), with all its whacky quoteing and escape constraints?    Or can this be done directly in a single find command,  using a blend of its many parameters?