Создайте меню bash на основе списка файлов (файлы карт на номера)

У меня была такая же проблема после установки nautilus для управления моими файлами в Xubuntu 11.10. Когда я вернулся к простому Ubuntu 12.04, проблема была там.

Простое решение, если это происходит ТОЛЬКО с вашим пользователем (рядом с тем, что уже было сказано desgua): удалить каталог ~/.local/share/application s, и все должно вернуться до нормального. Вы можете создать резервную копию некоторых ярлыков внутри этого каталога, если вы хотите их сохранить.

1
задан 13 April 2017 в 15:24

2 ответа

Вы также можете использовать glob оболочки, чтобы получить список файлов. Этот подход имеет то преимущество, что не использует внешнюю программу (find) и не требует каких-либо ограничений на тип файла (например, *war):

#!/usr/bin/env bash

## Collect the files in the array $files
files=( ~/foo/war/* )
## Enable extended globbing. This lets us use @(foo|bar) to
## match either 'foo' or 'bar'.
shopt -s extglob

## Start building the string to match against.
string="@(${files[0]}"
## Add the rest of the files to the string
for((i=1;i<${#files[@]};i++))
do
    string+="|${files[$i]}"
done
## Close the parenthesis. $string is now @(file1|file2|...|fileN)
string+=")"

## Show the menu. This will list all files and the string "quit"
select file in "${files[@]}" "quit"
do
    case $file in
    ## If the choice is one of the files (if it matches $string)
    $string)
        ## Do something here
        echo "$file"
        ## Uncomment this line if you don't want the menu to
        ## be shown again
        # break;
        ;;

    "quit")
        ## Exit
        exit;;
    *)
        file=""
        echo "Please choose a number from 1 to $((${#files[@]}+1))";;
    esac
done
5
ответ дан 23 May 2018 в 16:55
  • 1
    +1 - Это имеет то преимущество, что обработка имени файла полностью динамична. – Dennis Williamson 7 October 2015 в 01:28

select может сделать большую часть этого для вас, без особых усилий.

Как мне перевернуть список файлов в этот массив?

Вам на самом деле не нужно. select выводит ряд слов для отображения в качестве параметров. Они могут быть заданы непосредственно (select color in red green blue) или получены из расширения файла glob (select file in *.war), а также для расширения массива в словах в качестве примера, который вы нашли (select option in "${options[@]}").

Как превратить список файлов в этот массив?

Как мне получить строку с определенным смещением в параметрах?

Как я могу заставить пользователя попросить еще раз?

select делает это автоматически и сохраняет его в переменной, которую вы предоставляете. (Если вход пользователя недействителен, он сохраняет пустую строку.)

Как я могу заставить пользователя попросить еще раз?

Опять select делает это для вас, потому что select делает цикл, как while. Он будет продолжать просить, пока вы break не выйдете из цикла (или пока он не прочитает EOF, обычно вводимый Ctrl + D).

Могу ли я разрешить string stop остановить режим выбора?

echo "The following `*.war` archives were found; select one:"

# set the prompt used by select, replacing "#?"
PS3="Use number to select a file or 'stop' to cancel: "

# allow the user to choose a file
select filename in *.war
do
    # leave the loop if the user says 'stop'
    if [[ "$REPLY" == stop ]]; then break; fi

    # complain if no file was selected, and loop to ask again
    if [[ "$filename" == "" ]]
    then
        echo "'$REPLY' is not a valid number"
        continue
    fi

    # now we can use the selected file
    echo "$filename installed"

    # it'll ask for another unless we leave the loop
    break
done
3
ответ дан 23 May 2018 в 16:55
  • 1
    +1 - для не требуемого массива – Dennis Williamson 7 October 2015 в 01:35
  • 2
    +1 для использования приглашения PS3, но особенно для читаемого кода, который проще всего понять из всех трех ответов, для «noobs like me». – WinEunuuchs2Unix 1 October 2016 в 21:51

Другие вопросы по тегам:

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