Есть ли опция для вывода списка файлов без ссылки на расширение? [закрыто]

Обратите внимание, что ​​{1..20} не является оператором подстановки символов / подстановки. Это особая форма раскрытия фигурных скобок. автор zsh и скопирован с ограничениями и вариациями ksh93 и bash .

foo_ {0001..0030} .nc не расширяется в список совпадающих файлов он расширяется до foo_0001.nc , foo_0002.nc , ... foo_0030.nc независимо от того, являются ли файлы e xist или нет.

bash имеет то ограничение, что содержимое не может быть изменяемым. ksh93 и zsh не имеют этого ограничения.

Итак ls -d foo _ {$ ns .. $ ne}.nc будет работать в этих оболочках.

zsh также имеет оператор подстановки / подстановки для сопоставления диапазонов десятичных чисел.

ls -d foo_<1-30>.nc

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

ls -d foo_(<1-30>~^????).nc # needs extendedglob

( ~ is кроме ( and-not ) ), ^ равно не , поэтому ~ ^ равно , а не-не , поэтому и ).

Оператор не работает с переменными (поскольку он перекрывается с операторами перенаправления, он работает только при следовании <[цифры] - [цифры]> шаблон, чтобы максимально избежать конфликтов с перенаправлениями). Однако вы можете использовать этот синтаксис, чтобы обойти это:

ls -d ${~:-foo_<$ns-$ne>.nc}

Или более разборчиво:

pattern="foo_<$ns-$ne>.nc"
ls -d $~pattern
3
17.04.2017, 17:22
3 ответа

Что-то вроде ls | sed -e 's / \. [0-9] \ + $ //' | сортировать | uniq -c должен делать то, что вы хотите.

2
27.01.2020, 21:09

Другой подход: ls | вырезать -f1 -d. | uniq -c .

awk подход: ls | awk -F. '{a [$ 1] ++} END {for (b in a) {print b, a [b]}}'

(длинный) perl подход: ls | perl -e 'while (<>) {$ a {(split (/\./,$_)) [0]} ++} for (ключи сортировки% a) {print "$ _ $ a {$ _} \ n "} '

5
27.01.2020, 21:09

Я бы не советовал анализировать вывод ls, find и т. д. (см. ParsingLs — Wiki Грега для объяснения, почему это плохая идея).

Вместо этого расширение параметров в массиве bash может создать список без расширений файлов.

filelist=(*);                      # or filelist=(*.log.*) to be more precise
printf '%q\n' "${filelist[@]%.*}"  # or echo "${filelist[@]%.*}"

Затем, чтобы работать с файлами по отдельности..

for i in "${filelist[@]%.*}"; do
   echo "$i";
done

Для конкретной цели OP мы можем использовать bash ассоциативный массив ​​для хранения количества версий.

filelist=(*.log.*)

declare -A count
for i in "${filelist[@]%.*}"; do 
  (( count["$i"]++ )); 
done

for j in "${!count[@]}"; do 
  printf '%q\t%q\n' "$j" "${count[$j]}";
done | sort

report01.log    6
report02.log    6
report03.log    6
report04.log    6
report05.log    6
5
27.01.2020, 21:09

Теги

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