Опираясь на ответ 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
Использование 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.
Краткий ответ — использовать подоболочку для выполнения команды в не -текущем каталоге:
(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