Получите все файлы, имя которых запускают с числа

Файлы, имя которых запускается с числа, могли быть фильтрованы с regex методом

$ find . -iregex "./[1-9]+.+" 

Действительно ли возможно сделать его с подстановочными знаками,

Испытание на отказ

$ ls {0..9}*
ls: cannot access '1*': No such file or directory
ls: cannot access '2*': No such file or directory
ls: cannot access '3*': No such file or directory
ls: cannot access '5*': No such file or directory
ls: cannot access '6*': No such file or directory
ls: cannot access '7*': No such file or directory
ls: cannot access '8*': No such file or directory
1
задан 25 May 2019 в 06:19

1 ответ

Да, конечно, это. Давайте возьмем этот каталог в качестве примера:

$ ls
1file  4file  7file  8file fileNoNum

Теперь, для списка всех файлов (или директора), которые запускаются с числа можно сделать:

$ ls [0-9]*
1file  4file  7file  8file

Расширение оболочки Вы использовали, {0-9}* на самом деле расширится до:

ls '0*' '1*' '2*' '3*' '4*' '5*' '6*' '7' '8*' '9*'

Таким образом, Вы получите сообщение об ошибке для каждого числа, которое не является первым символом файла в Вашем текущем каталоге. Используя шаблон шарика [0-9] вместо этого избежит этих ошибок.

Причиной этого является та оболочка расширения ({x..y}) расширены оболочкой прежде чем быть переданным программе, которую Вы называете (ls в этом случае). Вы видите это в действии при помощи set -x:

$ set -x
$ ls {0..9}*
+ ls '0*' 1file '2*' '3*' 4file '5*' '6*' 7file 8file '9*'
ls: cannot access '0*': No such file or directory
ls: cannot access '2*': No such file or directory
ls: cannot access '3*': No such file or directory
ls: cannot access '5*': No such file or directory
ls: cannot access '6*': No such file or directory
ls: cannot access '9*': No such file or directory
 1file   4file   7file   8file

Как Вы видите выше, шаблоны на самом деле передали ls были расширены до любых файлов соответствия прежде ls был назван. Так 1* был преобразован в 1file, 4* кому: 4file, 7* кому: 7file и 8* кому: 8file. Остальные не могли быть расширены, так как не было никаких имен файлов соответствия, таким образом, они были переданы ls который попробованный для списка любых файлов, соответствующих им, не нашел ни один и жаловался. Как это произошло бы, сделал, чтобы Вы выполнили их непосредственно:

$ ls 9*
ls: cannot access '9*': No such file or directory

Сравните это с подходом шарика:

$ ls [0-9]*
+ ls 1file 4file 7file 8file
1file  4file  7file  8file

Здесь, еще раз, шарик был расширен перед вызовом ls но так как это - шарик, это было только расширено до соответствия именам файлов. Для дальнейшего иллюстрирования этого сравните то, что происходит, когда Вы повторяете шарик или расширение:

$ echo [0-9]
[0-9]
$ echo {0..9}
0 1 2 3 4 5 6 7 8 9

На отдельной ноте, Вашем find команда не делает то, что Вы думаете, что она делает. Это распечатает все имена файла или каталога в текущем каталоге, которые запускаются с числа, но также и всех файлов и поддиректоров любых каталогов, имя которых запускается с числа. См.:

$ tree
.
├── 1file
├── 1foo
│  └── file
├── file
└── foo
    └── 1file

$ find . -iregex "./[1-9]+.+" 
./1file
./1foo
./1foo/file

-iregex операнд find соответствует всему имени файла. Так ./foo/1file не был возвращен потому что ./foo не запускается с числа и ./1foo/file был возврат, хотя имя файла не запускается с числа, потому что название каталога, в котором находится файл, действительно запускается с числа.

Для нахождения всех файлов (и только файлов), которые запускаются с числа в этом каталоге или любых подкаталогах можно использовать:

$ find . -type f -name '[0-9]*'
./1file
./foo/1file
2
ответ дан 25 May 2019 в 06:19

Другие вопросы по тегам:

Похожие вопросы: