Более быстрый способ перехода в каталог после его перечисления в предыдущей команде?

Вы также можете пропустить произвольное количество строк в начале или в конце файла, используя программы headили tail.

По вашему конкретному вопросу

tail input.txt -n+7 | program.awk

подойдет, если ваш файл program.awkявляется исполняемым. В противном случае вы можете использовать

tail input.txt -n+7 | awk -f program.awk

Таким образом, вы сохраните сравнение для каждой строки, и вам не нужно менять логику вашего кода AWK.

tailначнет потоковую передачу текста, начиная с седьмой строки, пропуская шесть первых строк.

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

2
04.12.2019, 16:59
4 ответа

Вы можете использовать dirname, чтобы получить имя каталога, в котором находится искомый файл, и вы можете использовать tail -1, чтобы получить последнюю запись. Технически вы могли бы использовать head -2 | tail -1для получения второго списка в любое время, когда их два или более. Если есть только 1 список, он вернет этот 1.

Нравится:

cd $(dirname $(find. -name file.txt | tail -1))

или:

cd $(dirname $(find. -name file.txt | head -2 | tail -1))

Я не уверен, что это действительно быстрее, но это избавляет от необходимости использовать мышь для выбора текста и его копирования.

Вы можете встроить его в функцию в вашей оболочке rc, например, .bashrc.

function goto-file() {
    file=$1
    cd $(dirname $(find. -name $file | tail -1))
}

Тогда эффективность командной строки будет заключаться в том, чтобы просто набрать goto-file file.txt.

Может быть, лучше было бы позволить вам пройти путь, который вы хотите найти? Вот функция, которую я только что добавил в.bashrc:

function goto-file() {
    if [ $# -gt 2 -o $# -lt 1 ]; then
        echo "Usage: goto-file [path] filename"
    else
        if [ $# -eq 2 ]; then
            path=$1
            file=$2
        elif [ $# -eq 1 ]; then
            path='.'
            file=$1
        fi

        cd $(dirname $(find $path -name $file | tail -1))
    fi
}

Очень удобно. Спасибо.

2
27.01.2020, 21:55

(bashвариант ниже)

В оболочке zshпоследнее совпадение шаблона подстановки может быть получено путем добавления квалификатора подстановки ([-1])в конец шаблона. В этом примере мы ищем файлы, имена которых заканчиваются на.sh:

$ print -rC1./**/*.sh
./local/sbin/scheduled-backup.sh
./local/sbin/update-cvs.sh
./local/sbin/update-system.sh
./local/sbin/zerofill.sh
$ print -rC1./**/*.sh(.D[-1])
./local/sbin/zerofill.sh

Добавленные .и Dв квалификаторе гарантируют, что мы находим только обычные файлы и что мы также сопоставляем скрытые имена (, как с dotglob, установленным вbash).

Это можно использовать для перехода в каталог, содержащий найденный файл.:

$ cd./**/*.sh(.D[-1]:h)

(здесь используется модификатор стиля csh/vi -:h, чтобы получить заголовок(имя каталога )файла)

В качестве функции оболочки, которая принимает имя файла (, а не шаблон):

goto_file () cd./**/$1(.D[-1]:h)

Это не будет зависеть от правильных имен файлов (, не содержащих новых строк и т. д.)


В bash, предполагая, что вы сначала установили параметры оболочки globstarи dotglobс помощью shopt -s globstar dotglob, вы могли бы сделать то же самое в два этапа:

$ set --./**/*.sh
$ cd "$( dirname -- "${@: -1}" )"

Это устанавливает позиционные параметры в список совпадающих путей, затем использует последний из них в вызове dirnameи использует результат этого с cd. С bash,однако нет гарантии, что расширение глобуса будет обычным файлом.

Очевидно, вместо этого вы могли бы использовать именованный массив:

$ stuff=(./**/*.sh )
$ cd "$( dirname -- "${stuff[-1]}" )"

В качестве функции оболочки принимает имя файла (, а не шаблон):

goto_file () {
    local pathnames

    pathnames=(./**/"$1" )
    cd "$( dirname -- "${pathnames[-1]}" )"
}

Для этого необходимо, чтобы в вызывающей оболочке была установлена ​​по крайней мере опция globstar. Мы можем установить его по запросу:

goto_file () {
    local pathnames

    if [[ $BASHOPTS != *globstar* ]]; then
        shopt -s globstar
        trap 'shopt -u globstar' RETURN   # unset globstar on return
    fi

    pathnames=(./**/"$1" )
    cd "$( dirname -- "${pathnames[-1]}" )"
}

Это, как и вариант zsh, не будет полагаться на правильность имен файлов (, не содержащих символы новой строки и т. д. ), за исключением того, что имя каталога не может заканчиваться символами новой строки, поскольку они будут удалены при подстановка команды dirnameвозвращает свое значение.

3
27.01.2020, 21:55

Если вы используете xtermэмулятор терминала, вы можете привязатьdabbrev-expand()действие (, которое имитирует emacs' динамическое сокращение функцию )к какой-либо клавише.

Например, поместите файл ресурсов (, либо загруженный на X-сервер с xrdb, чтобы повлиять на xtermлюбого клиента к этому X-серверу, либо в файл XENVIRONMENT, чтобы все xterm вызов с машины, независимо от того, к какому X-серверу они подключаются, чтобы быть затронутым ), что-то вроде:

XTerm.VT100.translations:             #override\
        Meta <KeyPress> /: dabbrev-expand()

Затем с помощью Alt+/ , xtermобеспечивает завершение на основе того, что отображается на экране (, начиная с того, что ближе всего к курсору ).

Таким образом, после того, как ваш find...отобразит /folder/path/file-contents/file.txt, должно быть достаточно ввестиcd /Alt+/ для xterm, чтобы расширить это /до /folder/path/file-contents/file.txt, а затем удалить завершающую часть (или с zsh, добавьте (:h)или используйте Ctrl+W , если настроено рассматривать /как разделитель слов, например, сselect-word-style).

Этот подход не будет работать, если путь содержит пробелы или управляющие символы или символы в разложенной форме.

И если он содержит специальные символы оболочки (, такие как ', ", ;, &... ), вам нужно будет заключить их в кавычки (в zshвы можете использовать виджет quote-region(, привязанный к Alt+" по умолчанию, чтобы сделать это )для этого ).

0
27.01.2020, 21:55

Вы можете попробоватьcdi(https://github.com/antonioolf/cdi)

Этот инструмент командной строки был создан для улучшения просмотра каталогов. (Альтернативаcd).

По сути, это интерактивный, командный -браузер каталогов.

Все, что вам нужно сделать, это запустить команду cdi, перемещаться по папкам с помощью клавиш со стрелками(Вправо входит в папку, Влево идет назад, Вверх ] и Вниз прокручивает список ), когда вы найдете нужный каталог, просто нажмите Enter и настоящая команда cdбудет выполнена.

Взгляните на репозиторий

0
18.08.2020, 00:27

Теги

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