Linux 如何为输出添加行号,提示行,然后根据输入进行操作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9443694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:48:47  来源:igfitidea点击:

How to add line number for output, prompt for line, then act based on input?

linuxshell

提问by Yifan Zhang

I wrote a shell script like this:

我写了一个这样的shell脚本:

#! /bin/sh
...
ls | grep "android"
...

and the output is :

输出是:

android1 
android2
xx_android
...

I want to add a number in each file, like this:

我想在每个文件中添加一个数字,如下所示:

    1 android1 
    2 android2
    3 XX_android
    ...
    please choose your dir number:

and then wait for the user input line number x, the script reads the line number back then process the corresponding dir. How can we do this in shell ? Thanks !

然后等待用户输入行号x,脚本读取行号返回然后处理相应的目录。我们如何在 shell 中做到这一点?谢谢 !

采纳答案by kev

Instead of implementing the interaction, you can use built-in command select.

您可以使用内置命令,而不是实现交互select

select d in $(find . -type d -name '*android*'); do
    if [ -n "$d" ]; then
        # put your command here
        echo "$d selected"
    fi
done

回答by Karl Barker

If you pipe the result into cat, you can use the -noption to number each line like so:

如果将结果通过管道传输到cat,则可以使用该-n选项为每一行编号,如下所示:

ls | grep "android" | cat -n

回答by jweyrich

Pass -nto grep, as follows:

传递-ngrep,如下:

ls | grep -n "android"

From the grepman-page:

grep手册页:

 -n, --line-number
        Prefix each line of output with the line number within its input file.
 -n, --line-number
        Prefix each line of output with the line number within its input file.

回答by Scooby-2

This works for me:

这对我有用:

line-number=$(ls | grep -n "android" | cut -d: -f 1)

I use this in a script to remove sections of my sitemap.xml which I don't want Googlebot to crawl. I search for the URL (which is unique) and then find the line number using the above. Using simple maths the script then calculates the range of numbers required to delete the entire entry in the XML file.

我在脚本中使用它来删除我不希望 Googlebot 抓取的 sitemap.xml 部分。我搜索 URL(这是唯一的),然后使用上面的方法找到行号。然后脚本使用简单的数学计算删除 XML 文件中的整个条目所需的数字范围。

I agree with jweyrich regarding updating your question to get better answers.

我同意 jweyrich 关于更新您的问题以获得更好的答案。

回答by Traz

nl prints line numbers:

nl 打印行号:

ls | grep android | nl

回答by Brad Parks

The other answers on this page actually don't answer the question 100%. They don't show how to let the user interactively choose the file from another script.

此页面上的其他答案实际上并未 100% 回答问题。它们没有展示如何让用户以交互方式从另一个脚本中选择文件。

The following approach will allow you to do this, as can be seen in the example. Note that the select_from_listscript was pulled from this stackoverflow post

以下方法将允许您执行此操作,如示例中所示。请注意,该select_from_list脚本是从这个 stackoverflow 帖子中提取

$ ls 
android1        android4        android7        mac2            mac5
android2        android5        demo.sh         mac3            mac6
android3        android6        mac1            mac4            mac7

$ ./demo.sh
1) android1  3) android3  5) android5  7) android7
2) android2  4) android4  6) android6  8) Quit
Please select an item: 3
Contents of file selected by user: 2.3 Android 1.5 Cupcake (API 3)

Here's the demo.shand the script it uses to select an item from a list, select_from_list.sh

这是demo.sh用于从列表中选择项目的脚本和脚本,select_from_list.sh

demo.sh

演示文件

#!/usr/bin/env bash

# Ask the user to pick a file, and 
# cat the file contents if they select a file.
OUTPUT=$(\ls | grep android | select_from_list.sh | xargs cat)
STATUS=$? 

# Check if user selected something
if [ $STATUS == 0 ]
then
  echo "Contents of file selected by user: $OUTPUT"
else
  echo "Cancelled!"
fi

select_from_list.sh

select_from_list.sh

#!/usr/bin/env bash

prompt="Please select an item:"

options=()

if [ -z "" ]
then
  # Get options from PIPE
  input=$(cat /dev/stdin)
  while read -r line; do
    options+=("$line")
  done <<< "$input"
else
  # Get options from command line
  for var in "$@" 
  do
    options+=("$var") 
  done
fi

# Close stdin
0<&-
# open /dev/tty as stdin
exec 0</dev/tty

PS3="$prompt "
select opt in "${options[@]}" "Quit" ; do 
    if (( REPLY == 1 + ${#options[@]} )) ; then
        exit 1

    elif (( REPLY > 0 && REPLY <= ${#options[@]} )) ; then
        break

    else
        echo "Invalid option. Try another one."
    fi
done    
echo $opt