Лістинг із `ls` та регулярним виразом


15

Як я можу перерахувати файли з ім'ям файлу, що закінчується останнім символом та .txtрозширенням?

Я спробував, ls *+([[:digit:]]).txtале це правда для abc12.txtі abc2.txt.

Але мені потрібно лише дістати abc2.txt. Як я можу це зробити?

Чи є якась така форма, :digit:яка це зробить?


2
Слід зазначити , модель дійсна тільки розширена підстановка endabled: shopt -s extglob.
доношено успішно

Відповіді:


20

Як щодо:

ls *[!0-9][0-9].txt

На !початку групи доповнює своє значення.

Як зазначається в коментарях, це робиться баш, спробуйте, наприклад:

printf "%s\n" *[!0-9][0-9].txt

3
Зауважте, що bash (тобто ls) не підтримує регулярні вирази тут. Це вирази імен файлів (Globbing) . Різницю ви можете побачити вже у своєму прикладі: тут *є символи підстановки, яких немає в регулярних виразах, де ви б використовували .*для досягнення того ж. Регулярні вирази набагато потужніші, ніж глобальні.
Крістофер К.

3

Запитання запитувало регулярні вирази. Bash, і, отже ls, не підтримує тут регулярних виразів. Він підтримує вирази імен файлів ( Globbing ), форми підстановок. Регулярні вирази набагато сильніші за це.

Якщо ви дійсно хочете використовувати регулярні вирази, ви можете використовувати find -regexтакий:

find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt'

Знайти рекурсивно за замовчуванням, але lsце не так. Щоб знайти лише файли в поточному каталозі, ви можете відключити рекурсію за допомогою -maxdepth 1. Знайдіть збіги проти імені файлу з контуром, тому імена файлів починаються з того, що ./ви запускаєте знаходження в .. Регекс починається з того, \./щоб впоратися з цим. Зауважте, що в регулярному виразі .- це спеціальний символ, що відповідає будь-якому символу, але тут ми дійсно хочемо крапки, тому ми уникаємо його за допомогою косої риски. Ми робимо те ж саме для крапки .txt, оскільки в іншому випадку регулярний вираз також збігається Atxt. Цифрові класи такі ж, як і для глобусу, лише те, що вам потрібно ^замість !інвертувати клас символів.

Якщо ви хочете отримати вихід ls, ви можете використовувати -exec lsтак:

 find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt' -exec ls -lah {} \;

findпідтримує пару різних ароматів регексу. Ви можете вказати -regextype, наприклад:

find . -maxdepth 1 -regextype egrep -regex '\./.*[^0-9][0-9]\.txt'

Для мене можливі типи: 'findutils-default', 'awk', 'egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic' , 'posix-egrep', 'posix-extension', 'posix-minimal-basic', 'sed' Ви можете запустити, find -regextype helpщоб дізнатися, що підтримується у вашій системі.


0

З ksh розширеними глобусами (або bash -O extglobабо zsh -o kshglob), які ви вже використовуєте, це було б:

ls -d -- ?(*[![:digit:]])[[:digit:]].txt

Або

ls -d -- !(*[[:digit:]])[[:digit:]].txt

Якщо ви хочете , щоб відповідати на a1.txt і2.txt , але не a12.txtні 12.txt.

Однак зауважте, що в ksh та bash (якщо ви не встановите failglobможливість отримати поведінку, схожу на zsh), якщо цей шаблон не відповідає жодному файлу, шаблон буде переданий буквально ls, і якщо цей (дивним чином названий) файл трапиться існує, він буде перерахований, lsнавіть якщо він не відповідає самому шаблону.

Щоб включити .2.txt, встановіть dotglobпараметр в bash, додайте (D)Глоби класифікатор в zshабо набір FIGNOREдля !(.|..)в ksh93.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.