Как извлечь часть имени файла с определенным шаблоном?

Если вы используете оболочку bash, включите опцию globstar, чтобы **соответствовало внутри подкаталогов, а затем просто используйте grepкак обычно:

shopt -s globstar
grep -l hello **/index.php

(Вам нужно shopt -s globstarтолько один раз в оболочке, если вы не отключите эту опцию с помощью shopt -u globstar.)

0
04.09.2019, 15:41
3 ответа

Возможно:

for file_name in *0728*dat
do
  printf '%s\n' "${file_name%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9]_[0-9][0-9].dat}"
done

Это удаляет из конца каждого имени файла шаблон :8 цифр, подчеркивание, 2 цифры, подчеркивание, 2 цифры, подчеркивание, 2 цифры, затем .dat.

1
28.01.2020, 02:39

с помощью sed:

ls -a *0728*dat | sed 's/[0-9].*//'
amnbmnb_kjhkj_
amnbmnbm_jnjmnm_sd_
njnkjnjk_AbnBCBB_DE_

или

ls -a *0728*dat | sed "s/[0-9]\{8\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}\.dat$//"
0
28.01.2020, 02:39

Для следующего требуется bash4.4 или новее, GNU findи GNUsed(или, по крайней мере, findи sed, которые поддерживают NUL в качестве разделителя вывода/ввода):

$ mapfile -d '' files < <(find. -maxdepth 1 -type f -iname '*0728*.dat' -print0 | 
    sed -z 's:^\./::; s/[0-9][0-9_]\+.dat//')

Это заполняет массив bash(files)совпадающими именами файлов в текущем каталоге после того, как у них был начальный ./и расширение даты и времени и.dat, удаленное sed. Он использует NUL в качестве записи (, то есть разделителя имени файла ), чтобы избежать любых потенциальных проблем с пробелами, переводами строк -, мета-символами оболочки -и т. д. в любом из имен файлов.

findиспользуется, потому что вы никогда не должны использовать вывод lsв качестве входных данных для других программ или в качестве аргументов в команде другой программы -, строка -, это небезопасно и ненадежно. См. Почему не разборls(и что делать вместо )?

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

Пример:

$ touch amnbmnbm_jnjmnm_sd_07282019_14_13_17.dat amnbmnb_kjhkj_07282019_11_23_22.dat \
    njnkjnjk_AbnBCBB_DE_07282019_07_09_04.dat

$ mapfile -d '' files < <(find. -maxdepth 1 -type f -iname '*0728*.dat' -print0 | 
    sed -z 's:^\./::; s/[0-9][0-9_]\+.dat//')

$ typeset -p files
declare -a files=([0]="amnbmnbm_jnjmnm_sd_" [1]="amnbmnb_kjhkj_" [2]="njnkjnjk_AbnBCBB_DE_")

$ printf '%s\n' "${files[@]}"
amnbmnbm_jnjmnm_sd_
amnbmnb_kjhkj_
njnkjnjk_AbnBCBB_DE_
0
28.01.2020, 02:39

Теги

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