Как на Mac вывести содержимое не текущего каталога без отображения файлов резервных копий (оканчивающихся на ~), предпочтительно с помощью команды BSD ls?

Опираясь на ответ pfnuesel ,

{
    split($3, a, "|")
    split($4, b, "|")
    if (a[2] > b[2]){
        $3=b[1]"|"b[2]
        $4=a[1]"|"a[2]
    }
    key=$3" "$4
    split(arr[key], c, " ")
    if ($8 > c[8]  ||  ($8 == c[8] && $7 > c[7])){
        arr[key] = $0
    }
}
END{
    for (item in arr){
        print(arr[item])
    }
}

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

some_string | number

где пробелы даны только для иллюстрации, и строка не содержит символов |. Эти токены должны быть отсортированы на основе значений числа s; префиксы строки не сравниваются.

Как и в ответе pfnuesel , используется

awk -f script.awk file1

Точный интервал во входном файле теряется, но читаемый интервал между столбцами может быть (повторно )создан путем передачи через column -t; например,

awk -f script.awk file1 | column -t > file2

2
05.06.2019, 07:18
3 ответа

Вы можете выполнить lsв подоболочке:

(cd arg; ls -d *[^~])
4
27.01.2020, 21:52

Использование bashи ее переменной оболочки GLOBIGNOREвместе с macOSbasename:

$ mkdir dir
$ touch dir/file{1,2}{,~}
$ ls -R
dir

./dir:
file1   file1~  file2   file2~
$ GLOBIGNORE=*~
$ ls -d dir/*
dir/file1       dir/file2
$ basename -a dir/*
file1
file2

Установка GLOBIGNOREв список шаблонов с разделителями:-приведет к тому, что завершение имени файла будет игнорировать эти шаблоны.

Утилита basenameв macOS принимает более одного пути, если вы используете ее параметр -a, и возвращает список, состоящий только из частей имен файлов этих путей.

Вместо использования GLOBIGNORE(, который обеспечивает более общий способ игнорировать определенные расширения шаблона имени файла ), вы, очевидно, могли бы использовать свой шаблон*[!~](обратите внимание, что !отрицает класс символов в оболочке, в то время как ^отрицает класс символов в регулярных выражениях):

unset GLOBIGNORE
basename -a dir/*[!~]

... или вы можете просто установить GNU coreutils из Homebrew и использовать gls -B, как вы привыкли в системах Linux.

2
27.01.2020, 21:52

Краткий ответ — использовать подоболочку для выполнения команды в не -текущем каталоге:

(cd arg; ls -d *[^~])

Но чтобы создать общую функцию, которая работает для текущего каталога, а также для любого текущего каталога, отличного от -, мы можем добавить следующее в.bashrc(или в bashrc_aliases_lsBSD, источник.bashrc):

alias ls='/bin/ls'
alias   l=''
unalias l
function l () { ( if [[ -n "$@" ]]; then cd "$@"; fi ; /bin/ls -d *[^~] ) }

Если мы игнорируем упомянутое выше предпочтение использования BSD, мы можем использовать GNU lsбез каких-либо проблем, установив базовые утилиты GNU (, например, черезbrew install coreutils)и создав желаемые псевдонимы (вместо использования код выше )в.bashrc(или в bashrc_aliases_lsGNU, источник.bashrc):

alias ls='/usr/local/bin/gls'
alias l='/usr/local/bin/gls -B'

Мое собственное текущее решение состоит в том, чтобы использовать обе эти конструкции и переключаться между ними при необходимости, используя переменную, которую я вызываю LS_TYPE, и функцию, которую я вызываю ls-switch(, определенную в bashrc_aliases, полученную из .bashrc), источник которой один из двух конфигурационных файлов, содержащих эти две конструкции:

function ls-switch () {
    if [[ $LS_TYPE = "GNU" ]] ; then
        LS_TYPE="BSD"
        source ~/.config/bash/bashrc_aliases_lsBSD
    elif [[ $LS_TYPE = "BSD" ]] ; then
        LS_TYPE="GNU"
        source ~/.config/bash/bashrc_aliases_lsGNU
    fi
}

При таком расположении поведение lsи lпо умолчанию устанавливается в .bashrcс первым определением LS_TYPEи выбором исходного файла конфигурации, например:

LS_TYPE="BSD"
source ~/.config/bash/bashrc_aliases_lsBSD
1
27.01.2020, 21:52

Теги

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