объединить ls -alt с ссылкой для чтения

Вы можете сделать это с помощью встроенных функций (при условии, что вы используете GNU make):

VER=1.2.3
MINORVERTMP=$(subst.,,${VER})
MINORVER=$(word 1,${MINORVERTMP}).$(word 2,${MINORVERTMP})


all:
    @echo ${MINORVER}

Если вы можете использоватьbmake(BSD make ), у вас может быть больше (и, возможно, более простые )возможности:

VER=1.2.3

all: test1 test2

test1:
    # simple regular expression-based replace like sed
    @echo $@: ${VER:C,([^\.]*)\.([^\.]*).*,\1.\2,}

test2:
    # replace all dot to spaces (S),
    # print first and second element (:[1..2])
    # with dot separator (ts.)
    @echo $@: ${VER:S,.,,g:[1..2]:ts.}

1
28.07.2020, 04:32
1 ответ

С zshи GNUls:

files=(*(NDoN:P))
(($#files)) && ls -ltd -- ${(u)files}

Или с анонимной функцией для краткости:

(){ (($#)) && ls -ltd -- ${(u)@}; } *(NDoN:P)

где Nпозволяет nullglob,Ddotglobвключать скрытые файлы, oNпропускает сортировку, так как lsсортирует по mtime, а :Pвыполняет эквивалент GNU readlink -f. Флаг расширения параметра (u)удаляет дубликаты в массиве.

Или, если в текущем каталоге так много файлов, что описанное выше не удается с ошибкой слишком много аргументов , вы можете заставить zshвыполнить сортировку и передать список вls -U(в отключить собственную сортировку, требуется GNU lsили совместимый )через zargs, который, как и xargs, при необходимости разбивает список на более мелкие фрагменты.

autoload zargs
files=(*(ND-om:P))
zargs -r --eof= -- ${(u)files} '' ls -lUd --

Где -omсортирует по времени модификации после разрешения символической ссылки.

(beware zsh's :Pв настоящее время подавляет символические ссылки, которые имеют бесконечные циклы в своем разрешении ).

С помощью bashи инструментов GNU вы можете сделать что-то похожее на:

shopt -s nullglob dotglob
files=(*)
((${#files[@]})) &&
  printf '%s\0' "${files[@]}" | # prints as NUL-delimited records
  xargs -r0 readlink -zf -- |   # get absolute canonical path
  LC_ALL=C sort -zu |           # removes duplicates
  xargs -r0 stat --printf '%.9Y/%n\0' -- | # get mtime with max precision
  sort -rnz |                   # sort numerically in reverse
  cut -zd/ -f2- |               # remove timestamp added earlier
  xargs -r0 ls -lUd --          # pass to as many ls invocations as needed

При достаточно небольших списках файлов его можно упростить до:

shopt -s nullglob dotglob
files=(*)
((${#files[@]})) &&
  readlink -zf -- "${files[@]}" | # get absolute canonical path
  LC_ALL=C sort -zu |             # removes duplicates
  xargs -r0 ls -ltd --            # pass to ls

Посмотрите, как мы всегда передаем список файлов между инструментами в виде записей с разделителями NUL -. NUL — это единственный символ (и значение байта ), которые не могут встречаться в пути к файлу, поэтому это единственный безопасный метод.

В readlink -f * | sortвы передаете список файлов из readlinkв sortкак записи, разделенные символом новой строки -, поэтому имена файлов, содержащие символы новой строки, будут нарушены. Поскольку вы забыли --перед *, это также сломает имена файлов, начинающиеся с -.

Это намного хуже в ls -alt `cmd`, где на этот раз вывод cmdразделен на пробел, табуляцию и новую строку (, предполагая значение по умолчанию $IFS), и генерация имени файла выполняется на результирующих словах, так что он подавился бы еще большим количеством символов. Без -d,lsтакже перечисляет содержимое каталогов, которые он передает в качестве аргументов, а не только сами каталоги.

1
18.03.2021, 23:16

Теги

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