53

Contents of my dir are

$ ls -lrt
total 0
-rw-r--r-- 1 user1 admin 19 Oct  8 12:31 night.txt
-rw-r--r-- 1 user1 admin 19 Oct  8 12:31 noon.txt
-rw-r--r-- 1 user1 admin 38 Oct  8 12:31 day.txt

I would like to list out details of files that have a word in the filename as specified.

Example :

$ ls -lrt *day|night*
ls: *day: No such file or directory
bash: night.txt: command not found

Expected output

-rw-r--r-- 1 user1 admin 19 Oct  8 12:31 night.txt
-rw-r--r-- 1 user1 admin 38 Oct  8 12:31 day.txt

How to list out different files matching 2 different partterns, or in short how to use regex with ls, so that I could OR the filename parts.

Original scenarion, there are many file in the directory, have shortened the case for asking.

65

You don't even need extended globbing enabled to do what you want. This will work in bash:

ls {day*,night*}
  • 8
    No it doesn't: touch day.txt; touch night.txt; ls {*day,night*} results in ls: *day: No such file or directory – Matteo Oct 8 '12 at 16:46
  • 1
    I was adapting the original poster's text; I thought that was clear. sigh. Text updated. Surely you can see that the mechanism works? – itsbruce Oct 8 '12 at 16:50
  • 8
    Or possibly *{day,night}* is closer to what the OP wants. – derobert Oct 8 '12 at 17:24
25

There is no option in ls to filter on filename but in most of the shells there are globbing extension man bash /Pattern Matching

ksh

ls -lrtd -- *@(day|night)*

zsh

setopt extendedglob
ls -lrtd -- *(day|night)*

or:

setopt kshglob
ls -lrtd -- *@(day|night)*

bash

shopt -s extglob
ls -lrtd -- *@(day|night)*

In any of these three shells you can do this, but note that if one of the cases doesn't match any file, that pattern will be left unexpanded (e.g. *day* night1.txt othernight.txt if there is no file name containing day; see man bash /EXPANSION or /Brace Expansion specifically):

ls -lrtd -- *{day,night}*

In any shells you can do:

ls -lrtd -- *day* *night*

In zsh, if there's either no day or night file, the last two commands will fail; set the nonomatch or csh_null_glob option, or add (N) after each pattern to avoid this.

  • 1
    What about *{day,night}*. I'd edit it, but I don't know which shells support it? – Random832 Oct 8 '12 at 15:12
  • @Random832 Works in bash, ksh, and zsh (none need extended globbing), but not sh - however, Nahuel's last "all shells" example does work in sh. – Izkata Oct 8 '12 at 18:04
14

Shells do not uses regular expressions for argument expansion.

You can enable the extended pattern matching by

$ shopt -s extglob

and then

$ ls @(day|night).txt
day.txt   night.txt

See for example the Bash Reference Manual (Pattern Matching)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.