Tag Info

New answers tagged

5

Let us define foo: $ foo="*" Now, try echo without quotes: $ echo $foo File1 File2 The replacement of * with a list of filenames is called pathname expansion. It can be suppressed with with double-quotes: $ echo "$foo" * In addition, double-quotes will prevent brace expansion, tilde expansion, and word splitting. For completeness, try echo with ...


6

The answer of Michael is not correct. If the name has a space you are in trouble: $ ls aaa bbb ccc ccc a the last item is "ccc a" $ ls | grep -o -w '\w\{3\}' aaa bbb ccc ccc Celada said the correct answer: $ ls ??? aaa bbb ccc $ ls ????? ccc a


0

This is a start: $ ls | grep -o -w '\w\{3\}' png png log rdb png gfd gpg pub pdf out log gpg key txt txt the com pem VMs $ The count is $ ls | grep -o -w '\w\{3\}' | wc -l 19


3

In most cases, that would be the redirection operator (<): $ tr 'a' 'b' /path/to/file ## fails because `tr` works on streams tr: extra operand ‘file’ Try 'tr --help' for more information. $ tr 'a' 'b' < /path/to/file ## works because the file's contents are passed to tr Both command substitution and the redirection operator are defined by POSIX ...


1

With bash, globstar option enable, you can: shopt -s globstar less brscan/**/* But it also includes directories. With zsh, you can filter expansion to regular files only: less brscan/**/*(.) All of the above will fail if too many files return. The safe way is using find: find brscan -type f -exec less {} +


1

specify -not -type d to omit directories from the find result find -not -type d | xargs less or better: find -not -type d -print0 | xargs -0 less which handles filenames with spaces in them better.


2

It depends on the editing mode of your shell. For example I am using vi-mode and type Esc and * and the wildcards will get expanded.


2

How about echo rm build/* tmp/* Or, on my version of bash, hitting tabtab immediately after the wildcard gives me a list of matching files. To "delete files carefully", I would recommend either using the interaction flag to rm, or again prefixing with echo echo rm -i f*o rm -i f*o Admittedly neither will give you the list up front as preferred, ...


24

That's a really nice catch. From a quick look at the source code for GNU find, I would say this boils down to how fnmatch behaves on invalid byte sequences (pred_name_common in pred.c): b = fnmatch (str, base, flags) == 0; (...) return b; This code tests the return value of fnmatch for equality with 0, but does not check for errors; this results in any ...


13

find -name option uses shell pattern matching notation to perform matching filename. * is a pattern matching multiple characters, shall match a string of zero or more characters. find uses fnmatch to check pattern matching, so you can use ltrace to check the result: $ touch $'\U1212'aa $ touch D$'\351'sinstaller $ LC_ALL=en_US.utf8 ltrace -e fnmatch find ...


7

You have a file with a funny name, probably starting with a -. Remember that globs (like *) are expanded by your shell, not the command being run. As an example, say you have: $ ls -1 foo -q Simple enough directory, with two files in it. (The -1 option to coreutils ls makes its output single-column.) When you run du -sh *, the shell notices that the ...


4

Brace expansion happens before wildcard expansion, because brace expansion creates separate words, whereas wildcard expansion happens at the very end when the wildcard patterns are already in separate words. (Anyway, if it happened the other way round, then cp *.djvu{,.bk} would match nothing, because there is no file whose name ends with .djvu{,.bk}, and ...


8

What happens is that bash first expands *.djvu{,.bk} into *.djvu *.djvu.bk, and then does glob-expansion on those. This would explain what you observe: in your case, *.djvu, matches an existing file, say foo.djvu and expands into that, but *.djvu.bk matches no file, and thus expands as itself, *.djvu.bk. The order of expansion is specified in the bash ...


0

this is a great help to me. i had a need to create a set of subdirectories in multiple folders and something like: !/bin/sh cd /dest/cont for dir in */*/; do mkdir -p -- $dir/{FB,Video,Audio,proj}; done worked great except when a white space is encountered. is there a way to ignore spaces in the */*/ part of the arguments?


0

Should be \! name "RCS" and it works best on the first check in. sudo find ~/.his/etc \! -name "RCS" -ls sudo find -d ~/.his/etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir This last one also works very well for the cjeck in part filtering all RCS content on the file name: sudo find -d ~/.his/etc -type f | grep -v RCS | xargs sudo ci -l -mir -t-ir


0

This is a good one from the old Unix Masters (tested on FreeBSD 10.1) if you want to version control (with RCS check in locked: ci -l with a brief comment as ir: for initial release) your /etc/* config files on ~/.his/etc sudo rsync -av /etc/ ~/.his sudo find -d ~/.his/etc -type d -exec echo '{}/RCS' \; | xargs sudo mkdir -p sudo find -d ~/.his/etc \! ...


10

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may ...


1

I'd think you could use ls -A instead, specifically: chown -R username:groupname $(ls -A | grep '^\.') This does what you'd expect .* to do, match all files in the current directory that begin with a ., excluding . and ... But note this won't behave identically to a bash glob if you need it to match funky file names, like files with spaces in them.


1

A variation of Chris Down solution that filter just hidden directories and removes the -R options. Your original requirement was to change ownership and group classification of hidden directories, not their content. find /home/username -maxdepth 1 -type d -name '.*' -exec chown user:group {} +


6

If the directory itself shares the same ownership as its files (hidden or not), then you can chown it recursively instead. The -R option will include hidden files when recursing inside the current directory. $ chown user:group . -R # Will include all hidden files


10

Using the extended globbing (shopt -s extglob), you can use .!(.|) i.e. dot not followed by dot or nothing.


6

Consider using find (-maxdepth is a non-POSIX extension, but it should be readily available on Linux): find . -maxdepth 1 -type d -name '.*' -exec chown -R user:group {} +


17

I always get burned when I try using .* for anything and long ago switched to using character classes: chown -R username.groupname .[A-Za-z]* is how I would have done this. Edit: someone pointed out that this doesn't get, for example dot files such as ._Library. The catch all character class to use would be chown -R username.groupname .[A-Za-z0-9_-]*


-1

To add to the other answers, a single ? will translate to a single character filename and ?? will match filenames that has only two characters and so on. [root@mercy testdir_2]# ls ion it r [root@mercy testdir_2]# ls ? r [root@mercy testdir_2]# ls ?? it [root@mercy 1 testdir_2]# ls ??? ion [root@mercy testdir_2]#


2

You can't do shell globbing without matching files. You need brace expansion: gitk master@{{1..5}} or: gitk master@{{1,2,3,4,5}} With form {x..y}, you need zsh 2.6-beta4 and later, bash 3.0 and later, ksh93r and later. {x,y} was original in csh and copied to Bourne like shell first in ksh.


1

In at least bash you can use ranges, e.g. $ echo gitk master@{{1..5}} gitk master@{1} master@{2} master@{3} master@{4} master@{5} Obviously the echo is used above just to show what happens. It works for letters as well: $ echo /dev/sd{x..z} /dev/sdx /dev/sdy /dev/sdz Note: the is glob matching, and there is regex matching. These are two distinct ...


1

Add this in ~/.bashrc: alias cp='cp 2> /dev/null' then: source ~/.bashrc


1

Your question is not clear. The most sensible thing to do would be to not run cp at all when the wildcard doesn't match any file, rather than run cp and hide the error message. To do that, if the shell is bash, set the nullglob option so that the wildcard pattern expands to nothing if it doesn't match any files. Then check whether the pattern expanded to ...


4

To suppress error output in bash, append 2>/dev/null to the end of your command. This redirects filehandle 2 (STDERR) to /dev/null. There are similar constructs in other shells, though the specific construct may vary slightly.


2

Redirect the error message (STDERR) to /dev/null: root@ubuntu:~$ cp /srv/ftp/201*/wha*/*.jj ~/. 2>/dev/null Example: $ cp /srv/ftp/201*/wha*/*.jj ~/. ##Error message gets printed cp: cannot stat ‘/srv/ftp/201*/wha*/*.jj’: No such file or directory $ cp /srv/ftp/201*/wha*/*.jj ~/. 2>/dev/null ##No error message gets printed


3

Either you have nothing in your current directory that match your globbing pattern (then the pattern will stay as it is), or you have disabled globbing by shell option -f (or set -o noglob).



Top 50 recent answers are included