Tag Info

Hot answers tagged

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 ...


10

Option 1 - using just ls: With extended bash globbing turned on (shopt -s extglob) you can do: ls !(one*)/*.png Option 2 - combining ls and grep: You can combine ls with grep -v e.g. ls */*.png | grep -v "one/" Option 3 - (the best IMO) but uses find not ls: For recursive searching of all subdirectories using find find . -type f -name "*.png" ...


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 ...


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 ...


6

Not yet. With the extglob option, bash adds some of ksh extended globbing operators but not the {x,y}(pattern) one. In ksh93, you use: {5}(?) With zsh with the extendedglob option: ?(#c5) (you'll notice none of them are shorter than ????? though). In bash, you could do: $(printf '%.0s?' {1..5}) though that's hardly an improvement and relies on ...


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


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 ...


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 ...


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 ...


3

I think you are looking for the brace expansion {asd,qwe}: $ ls foo.{asd,qwe} foo.asd foo.qwe


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, ...


2

The globbing pattern would be ls foo.@(asd|qwe). This works out of the box in ksh; in bash also if "extended globbing" is activated with shopt -s extglob; in zsh if ksh-style globs are activated with setopt ksh_glob.


2

For various reasons related to whitespace issues, etc., it is not advisable to parse the output of ls. An alternative, which uses GNU versions of find, sort, sed: find . -mindepth 1 -maxdepth 1 -printf "%A@ %f\0" | sort -rnz | sed -z 's/^[0-9.]\+ //' find is, of course, much more flexible than ls when it comes to listing and filtering files, but it ...


2

Background reading: Why does my shell script choke on whitespace or other special characters?, Why you shouldn't parse the output of ls Setting IFS to a newline means that only newlines, and not spaces and tabs, will be treated as separators during the expansion of the command substitution. Your method will not support file names that contain newlines; this ...


1

In zsh, put setopt extended_glob in your ~/.zshrc. Then you can use the wildcard pattern ^one to exclude the directory called one. ls ^one/*.png If you want to recurse into subdirectories, use **/ for recursive globbing. To exclude the directory called one at the toplevel, as well as the toplevel directory: ls ^one/**/*.png To exclude files in a ...


1

Do you really mean adding * in filename? Or you mean the output of ls gives filename ending in * if it has execute permission? If only output problem of ls, you could simply solve by: replace ls to \ls, this is to use un-aliased version of ls, which doesn't output *


1

You can use something like this: ls -1Atu | while IFS= read -r entry; do echo "$entry" done With this example, the output is generated once, and the while read entry section causes the output from ls to be parsed line-by-line, which solves the issue with your for example where everything was getting placed in $i in a single round.


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.



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