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

LinuxShell

Linux Problem Overview


I wrote a shell script like this:

#! /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 !

Linux Solutions


Solution 1 - Linux

nl prints line numbers:

ls | grep android | nl

Solution 2 - Linux

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

ls | grep "android" | cat -n

Solution 3 - Linux

Pass -n to grep, as follows:

ls | grep -n "android"

From the grep man-page:

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

Solution 4 - Linux

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

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

Solution 5 - Linux

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.

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

$ 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.sh and the script it uses to select an item from a list, 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

#!/usr/bin/env bash

prompt="Please select an item:"

options=()

if [ -z "$1" ]
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

Solution 6 - Linux

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.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYifan ZhangView Question on Stackoverflow
Solution 1 - LinuxTrazView Answer on Stackoverflow
Solution 2 - LinuxKarl BarkerView Answer on Stackoverflow
Solution 3 - LinuxjweyrichView Answer on Stackoverflow
Solution 4 - LinuxkevView Answer on Stackoverflow
Solution 5 - LinuxBrad ParksView Answer on Stackoverflow
Solution 6 - LinuxScooby-2View Answer on Stackoverflow