AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 511127
Accepted
Jeffrey L. Roberts
Jeffrey L. Roberts
Asked: 2019-04-08 14:42:52 +0800 CST2019-04-08 14:42:52 +0800 CST 2019-04-08 14:42:52 +0800 CST

BASH 列出可能的文件并选择一个

  • 772

我希望能够运行一个 bash 脚本,让它列出可能的文件作为选项来选择一个,然后通过 scp 将该文件传输到目标......

scp 部分没问题,但我如何获得文件列表并能够选择一个对我来说是具有挑战性的......

$ ./script
Please select a file.
[0] ~/Desktop/ScreenShot-04-06-19-01:02:33.png
[1] ~/Desktop/ScreenShot-04-06-19-01:03:33.png
[2] ~/Desktop/ScreenShot-04-06-19-01:04:33.png
Enter File Index ID: 
bash shell-script
  • 3 3 个回答
  • 5363 Views

3 个回答

  • Voted
  1. ctac_
    2019-04-09T01:05:07+08:002019-04-09T01:05:07+08:00

    另一种方法是使用 select from bash :

    $ cat myscript
    PS3="Enter File Index ID: "
    echo "Please select a file."
    select file ; do
      [ "$file" ] &&
       {
         echo "$file"
         break
       } ||
       {
         echo "bad choice"
         break
       }
    done
    

    你这样称呼它:

    myscript ~/Desktop/*.png
    

    PS:将 script 重命名为 myscript 因为 script 是一个命令。
    看man script

    • 4
  2. Kusalananda
    2019-04-09T02:19:52+08:002019-04-09T02:19:52+08:00

    要提供一个交互式菜单,bash用户可以从中选择多个文件路径名,您可能需要使用以下内容:

    #!/bin/bash
    
    files=( "$HOME/Desktop/ScreenShot-"*.png )
    
    PS3='Select file to upload, or 0 to exit: '
    select file in "${files[@]}"; do
        if [[ $REPLY == "0" ]]; then
            echo 'Bye!' >&2
            exit
        elif [[ -z $file ]]; then
            echo 'Invalid choice, try again' >&2
        else
            break
        fi
    done
    
    # use scp to upload "$file" here
    

    在这里,我们使用bash语句select来提供菜单,并使用PS3第三级提示来提供自定义提示。

    0用户可以通过在提示符处输入退出脚本而不从列表中选择文件。如果给出了无效的响应,用户将有另一个机会选择一个文件。Enter在提示符处按下可重新显示菜单。

    循环内部的逻辑如何select制定并不重要,只要脚本在$REPLY(用户输入的实际值)为空时终止,并在(从数组中选取的值)为空0时重试。$file另一种select语句体可能看起来像

    if [[ $REPLY == "0" ]]; then
        echo 'Bye!' >&2
        exit
    elif [[ -n $file ]]; then
        break
    fi
    
    echo 'Invalid choice, try again' >&2
    

    文件名通过 shell glob 插入到命名数组中。您还可以使用从脚本的命令行获取相关文件

    files=( "$@" )
    

    在 POSIX shell 中,您通常无权访问命名数组或select. 相反,你可以做类似的事情

    #!/bin/sh
    
    set -- "$HOME/Desktop/ScreenShot-"*.png
    
    while true; do
        i=0
        for pathname do
            i=$(( i + 1 ))
            printf '%d) %s\n' "$i" "$pathname" >&2
        done
    
        printf 'Select file to upload, or 0 to exit: ' >&2
        read -r reply
    
        number=$(printf '%s\n' "$reply" | tr -dc '[:digit:]')
    
        if [ "$number" = "0" ]; then
            echo 'Bye!' >&2
            exit
        elif [ "$number" -gt "$#" ]; then
            echo 'Invalid choice, try again' >&2
        else
            break
        fi
    done
    
    shift "$(( number - 1 ))"
    file=$1
    
    # use scp to upload "$file" here
    

    这是一个相当常见的输入循环,它会迭代直到用户输入有效的条目(或直到0输入并且脚本退出)。每次输入错误都会重新显示菜单。

    路径名通过 shell glob 被带入位置参数列表,就像在bash变体中一样,但是菜单是手动打印的,每个输出的菜单条目都会增加一个整数。

    shift末尾的 将位置参数列表开头的条目移开,以便成为$1用户想要上传的路径名。

    要改为使用命令行上给出的路径名,只需删除初始set命令。

    • 3
  3. Best Answer
    Irfan Latif
    2019-04-08T16:28:05+08:002019-04-08T16:28:05+08:00

    这就是我在 bash 脚本中的做法(也适用于 POSIXsh脚本):

    echo 'Please select a file.'
    
    n=0
    for img in ~/Desktop/ScreenShot-*.png
    do
        n=$((n+1))
        printf "[%s] %s\n" "$n" "$img"
        eval "img${n}=\$img"
    done
    
    if [ "$n" -eq 0 ]
    then
        echo >&2 No images found.
        exit
    fi
    
    printf 'Enter File Index ID (1 to %s): ' "$n"
    read -r num
    num=$(printf '%s\n' "$num" | tr -dc '[:digit:]')
    
    if [ "$num" -le 0 ] || [ "$num" -gt "$n" ]
    then
        echo >&2 Wrong selection.
        exit 1
    else
        eval "IMG=\$img${num}"
        echo Selected image is "$IMG"
    fi
    
    • 2

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • MySQL Select with function IN () with bash array

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve