Tag Info

Hot answers tagged

82

ls lists the files and content of directories it is being passed as arguments, and if no argument is given, it lists the current directory. It can also be passed a number of options that affect its behaviour (see man ls for details). If ls is being passed an argument called *, it will look for a file or directory called * in the current directory and list ...


67

The a* and *a* syntax is implemented by the shell, not by the ls command. When you type ls a* at your shell prompt, the shell expands a* to a list of existing all files in the current directory whose names start with a. For example, it might expand a* to the sequence a1 a2 a3, and pass those as arguments to ls. The ls command itself never sees the * ...


47

From man bash: *(pattern-list) Matches zero or more occurrences of the given patterns You have a glob expression which matches files beginning with zero or more 1s - which is all files. One simple way to disable this globbing behaviour is to \ escape the parentheses: rm *\(1\)* Otherwise you can use shopt -u extglob to disable the ...


45

Zsh mv Foo/*(DN) Bar/ or setopt -s glob_dots mv Foo/*(N) Bar/ (Leave out the (N) if you know the directory is not empty.) Bash shopt -s dotglob nullglob mv Foo/* Bar/ Ksh93 If you know the directory is not empty: FIGNORE='.?(.)' mv Foo/* Bar/ Standard (POSIX) sh for x in Foo/* Foo/.[!.]* Foo/..?*; do if [ -e "$x" ]; then mv -- "$x" Bar/ done ...


42

Rsync's filter rules can seem daunting when you read the manual, but there are a few simple principles that suffice in many cases: Inclusions and exclusions: Excluding files by name or by location is easy: --exclude=*~, --exclude=/some/relative/location. If you only want to match a few files or locations, include them, include every directory leading to ...


41

You need to quote your argument error* because the shell expands it. So what you're actually running now is find -name error_log, because that's what the shell can expand it to (there's a file named error_log in your current directory). find . -name 'error*' Is the correct invocation for your use case.


39

This is not a bug in the cp command. When you enter cp *.pdf, cp never sees the actual wildcards because the wildcards are expanded by bash, not by cp. How will cp know that you have entered only one argument? This is a side effect of bash wildcards and cannot be called a bug.


37

$ touch ./-c $'a\n12\tb' foo $ du -hs * 0 a 12 b 0 foo 0 total As you can see, the -c file was taken as an option to du and is not reported (and you see the total line because of du -c). Also, the file called a\n12\tb is making us think that there are files called a and b. $ du -hs -- * 0 a 12 b 0 -c 0 foo ...


33

Unfortunately, for historical reasons, different tools have slightly different regular expression syntax, and sometimes some implementations have extensions that are not supported by other tools. While there is a common ground, it seems like every tool writer made some different choices. The consequence is that if you have a regular expression that works in ...


31

A shell assignment is a single word, with no space after the equal sign. So what you wrote assigns an empty value to thefile; furthermore, since the assignment is grouped with a command, it makes thefile an environment variable and the assignment is local to that particular command, i.e. only the call to ls sees the assigned value. You want to capture the ...


29

Globs are not regular expressions. In general, the shell will try to interpret anything you type on the command line that you don't quote as a glob. Shells are not required to support regular expressions at all (although in reality many of the fancier more modern ones do, e.g. the =~ regex match operator in the bash [[ construct). The .??* is a glob. ...


26

The command ls defaults to ls .: List all entries in the current directory. The command ls * means 'run ls on the expansion of the * shell pattern' The * pattern is processed by the shell, and expands to all entries in the current directory, except those that start with a .. It will go one level deep. The interpretation of double or triple * patterns ...


25

The latest (as of 2013) version of the POSIX spec for the rm utility is here (and the previous one there) and forbids the deletion of . and ... If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic ...


24

You can use the mogrify command for this. Normally, it modifies files in-place, but when converting formats, it writes a new file (just changing the extension to match the new format). Thus: mogrify -format pdf -- *.jpg (Like enzotib's ./*.jpg, the -- prevents any strange filenames from being interpreted as switches. Most commands recognize -- to mean ...


24

See Keith Thompson’s answer; but to explain why ls --directory a* shows files and directories: The --directory option does not suppress non-directory files. Instead, it lists the directories as such, while it would otherwise list their content. Example: $ mkdir foo $ touch foo/bar $ ls foo bar $ ls --directory foo foo


23

If the last argument was a directory, you just moved all of the files and directories in your current working directory (except those whose names begin with dots) into that directory. If there were two files, the first file may have overwritten the second file. Here are some demonstrations: More than two files and the last argument is a file $ mkdir d1 d2 ...


21

Those are not regular expressions, they are examples of Bash's parameter expansion: the substitution of a variable or a special parameter by its value. The Wooledge Wiki has a good explanation. Basically, in the example you have, ${0##*/} translates as: for the variable $0, and the pattern '/', the two hashes mean from the beginning of the parameter, ...


20

This is actually done by your shell, not by ls. In bash, you'd use: shopt -s nocaseglob and then run your command. Or in zsh: unsetopt CASE_GLOB and then your command. You might want to put that into .bashrc or .zshrc, respectively. Alternatively, with zsh: setopt extendedglob ls -d -- (#i)*abc* (that is turn case insensitive globbing on on a ...


20

[ is an alias for the test command. Unix Version 6 had an if command, but Version 7 (1979) came with the new Bourne shell that had a few programming constructs including the if-then-else-elif-fi construct, and Unix version 7 added a test command that performed most of the "tests" that were carried out by the if command in older versions. [ was made an alias ...


19

You seem to understand what is happening perfectly well. In your example, *pdf indeed expands to file1.pdf file2.pdf this_is_a_folder.pdf. I don't see what's confusing you. cp is doing exactly what it should, you are telling it to copy file1.pdf and file2.pdf into this_is_a_folder.pdf and that is exactly what it is doing. There is no bug, it is working as ...


18

The difference between [[ … ]] and [ … ] is mostly covered in using single or double bracket - bash. Crucially, [[ … ]] is special syntax, whereas [ is a funny-looking name for a command. [[ … ]] has special syntax rules for what's inside, [ … ] doesn't. With the added wrinkle of a wildcard, here's how [[ $a == z* ]] is evaluated: Parse the command: this ...


17

find is very useful for selectively performing actions on a whole tree. find . -type f -name ".Apple*" -delete Here, the -type f makes sure it's a file, not a directory, and may not be exactly what you want since it will also skip symlinks, sockets and other things. You can use ! -type d, which literally means not directories, but then you might also ...


17

You can use the -delete flag of find (first test with -ls) find -not -name "*.c" -delete If you do not want to use find, but only files in the current directory, you could do rm !(*.c) Make sure in bash that with shopt -s extglob the correct globbing is set. Additionally, if you have globstar set (shopt -s globstar), you can act recursively (for bash ...


17

Bash, ksh and zsh have better solutions, but in this answer I assume a POSIX shell. The pattern .[!.]* matches all files that begin with a dot followed by a non-dot character. (Note that [^.] is supported by some shells but not all, the portable syntax for character set complement in wildcard patterns is [!.].) It therefore excludes . and .., but also files ...


16

It isn't deleting them because it recognises the filenames as arguments (unquoted, in this situation * expands to -f -i ize). To delete these files, either do rm -- *, or rm ./*. -- signifies the end of arguments, ./ uses the link to the current directory to circumvent rm's argument detection. Generally ./* is preferable, as some programs do not accept -- ...


16

The * (star, or asterisk) is a special character which is (usually) interpreted by the shell before it is given the command. It is (usually) expanded to all filenames except those with leading dots. See the bash manual about pattern matching for more information. If placed in quotes the star will not be interpreted by the shell and is given to the command ...


16

No need for any fancy stuff. Simply escape the ? so that it's not considered part of the glob: rm -f ./\?* This works for ! too: rm -f ./\!* Or in one fell swoop: rm -f ./{\?,\!}* Update Just noticed that you were suggesting to grep the output of ls. I wanted to bring your attention to the fact that you shouldn't parse the output of ls


15

grep -r foo * doesn't look for matches in hidden files or directories, also * is expanded by the shell so you might end up with an Argument list too long error when there are a lot of entries in the current directory, or some other errors or misbehaviour if the name of some of the files or directories starts with a dash character. Invocation grep -r foo . ...


14

Rsync handles this nicely. Example copy all: rsync -aP /folder1/* /folder/2 Example copy all with exclusion: rsync -aP --exclude=x /folder1/* /folder2/ The -aP switch: a: Similar to cp -a, recursive, etc. P: Shows progress, a nice feature of rsync.


14

Use */ to match only directories. chmod g+s /var/www/*/ To match all directories and subdirectories use **/*/ (provided you have globstar enabled in bash): shopt -s globstar chmod g+s /var/www/**/*/



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