Как сопоставить шаблоны без учета регистра с ls?

58

Я хотел бы перечислить все файлы, соответствующие определенному шаблону, игнорируя регистр.

Например, я запускаю следующие команды:

ls *abc*

Я хочу видеть все файлы, которые имеют "abc" как часть имени файла, игнорируя регистр, как

-rw-r--r-- 1 mtk mtk 0 Sep 21 08:12 file1abc.txt
-rw-r--r-- 1 mtk mtk 0 Sep 21 08:12 file2ABC.txt

Запись

Я искал справочную страницу для дела, но не смог ничего найти.

холодный морской тропический воздух
источник

Ответы:

65

Это на самом деле делается вашей оболочкой, а не ls.

В bash, вы бы использовали:

shopt -s nocaseglob

и затем запустите вашу команду.

Или в zsh:

unsetopt CASE_GLOB

Или в яше

set +o case-glob

а потом твоя команда.

Возможно, вы захотите вставить это .bashrc, .zshrcили .yashrc, соответственно.

В качестве альтернативы, с Zsh:

setopt extendedglob
ls -d -- (#i)*abc*

(то есть глобализация без учета регистра на основе подстановочных знаков)

С кш93:

ls -d -- ~(i:*abc*)

Вы хотите, чтобы globbing работал иначе, lsпоскольку это все файлы, передаваемые lsоболочкой.

Полемон
источник
В bash, как восстановить исходные настройки, если я использую shport -s nocaseglob?
MTK
6
@mtk: чтобы установить опцию, вы используете shopt -s; чтобы сбросить его, вы используете shopt -u. Кроме того , вы можете обернуть все в субоболочке с помощью ( )так что настройка не влияет на родительскую оболочку: (shopt -s nocaseglob ; ls *abc*).
Руах
Таким образом, в POSIX, SUS или что-то в этом роде нет никаких переносимых способов (кроме [aA][bB][cC])?
Тимоти Гу
Отличное решение, я не могу поверить, что я не сталкивался с shoptкомандой за последние 15 лет использования bash!
Реза Санаи
Jfg956 ответ правильный (следующий). Зачем менять поведение оболочки, когда у вас есть регулярное выражение для этого?
EnzoR
20

Как объяснил polemon, это оболочка (не ls), которая распространяется *abc*на список файлов. Это называется сопоставлением с образцом .

Помимо изменения всего поведения сопоставления с образцом для игнорирования регистра, вы можете использовать другую форму сопоставления с образцом, чем *. Следующее будет делать то, что вы хотите в bash:

ls *[aA][bB][cC]*

От Bash Man:

[...] Соответствует любому из вложенных символов.

Это позволяет более точно сопоставлять зерно, где вы можете использовать *[aA][bB]c*для сопоставления abcили ABcнет, abCили ABC. Или пример на французском, где я могу захотеть сопоставить все экземпляры eперсонажа:

ls *[eéèêëEÉÈÊË]*
jfg956
источник
1
К сожалению, такой подход быстро становится громоздким, поскольку шаблон становится длиннее. Но для коротких вещей это работает.
Дероберт
@derobert: полностью верно, особенно (и, вероятно, это так), оболочка оптимизировала регистр игнорирования соответствия, поместив все имена файлов и запрос на совпадение в нижнем регистре перед сравнением. Тем не менее, [...]во многих случаях они могут быть полезны, и я, хотя и заслуживал упоминания.
jfg956
1
Это правильный ответ. Изменение поведения оболочки не является.
EnzoR
Если языковой стандарт установлен правильно, вы сможете использовать классы эквивалентности [[=e=][=E=]].
Бенджамин В.
8

Вы также можете добавить -i(--ignore-case) параметр, grepчтобы получить и ниже вывод.

[root@localhost ~]# ls -l | grep -i abc
-rw-r--r--  1 root root    0 Feb 25 20:41 fileabc.txt
-rw-r--r--  1 root root    0 Feb 25 20:41 fileABC.txt
дворняжка
источник
Сопоставление с образцом имеет лучшую производительность по сравнению с grep, потому что grep должен собрать все и затем отфильтровать. Имеет заметную разницу при работе с папками большего размера.
Оми
@Omi Кроме того, регулярные выражения предназначены для текста , в частности строк текста. Имена файлов могут содержать переводы строк.
Кусалананда
3

Я не думаю, что это возможно с ls, но вместо этого вы можете использовать find:

find . -maxdepth 1 -iname '*abc*'
мат
источник
0

используйте следующий код:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE
user1678213
источник
Для чего нужна переменная LC_COLLATE? можешь объяснить дальше.
MTK
нажмите на ссылку, чтобы узнать об этом @mtk
user1678213
0

Вы можете GREP файл, используя -iкоторый добавляет нечувствительный параметр.

Например, чтобы найти оба, abcи ABCвы можете запустить эту команду

    [root@mtk bin]# ls -l | grep -i abc
    640K -rw-r--r-- 1 mtk mtk 639K Sep 21 08:12 file1abc.txt
    676K -rw-r--r-- 1 mtk mtk 674K Sep 21 08:12 file2ABC.txt
Луис Перес
источник
5
Луис Перес: Думаю, вы -iнигде не использовали опцию в своей команде.
Дворняга
-2

В tcsh установите псевдоним в .aliases

alias lsnc "ls BS!* | sort -f "

(«BS» = одна «обратная косая черта»; я должен был использовать ее, чтобы она отображалась в моем браузере.)

и использовать lsncвместоls

В bash попробуйте псевдоним в .bash_aliases, например

lsnc() { ls $1 | sort -f ; }

С опциями ls, например ls -l, вот простое исправление:

Tcsh:

alias lsncl "ls -l BS!* | sort -f -k 9"

Баш:

lsncl() { ls -l $1 | sort -f -k 9 ; }
Лестер Ингбер
источник
Вы уверены, что не пропустили ' =' после lsnocase?
Антон
Anthon: (пересмотренные) lsnc и lsncl работают для меня в tcsh и bash на Cygwin и Ubuntu. Обратите внимание, что для bash я использую функцию, а не «псевдоним» как таковой. Лестер
Лестер Ингбер
Anthon: Да, вы можете использовать псевдоним в bash, например, псевдоним lsncl = 'ls -l $ 1 | sort -f -k 9 '
Лестер Ингбер
Этот ответ не относится к конкретному вопросу, который хочет передать файлы, переданные ls, для обработки без учета регистра. Если оболочка проходит проходит слишком мало файлов ls, нет ничего , lsи sortможет может исправить ситуацию. Как отмечалось в других ответах, проблема должна решаться в оболочке, а не с помощью lsсинтаксиса.
Марк Стосберг