Get ony by one the results from find/locate
Question
How can I get 1 by 1 the results of a command like
# locate file.txt
/home/alex/file.txt
/backup/file.txt
What I want to do is to make an interactive script where to ask: Which of the following files would you like to copy/recover? [1],[2]:
Example:
filetorecover.txt
_________________
file.txt
file1.txt
...
./recover filestorecover.txt /home/alex/data/
file.txt could not be located at /home/alex/data, but it was locate here:
[1] /home/alex/files/
[2] /backup/file.txt
- filestorecover => is the file that contains file to look for
- /home/alex/files/ => is the main folder where to look for and if the file is not located there, then do a
locate file.txt
So, mainly I am looking for a way of grabbing those X results from find or locate one by one for the late use as explained above.
UPDATE
Is it possible to see the most common path for find/locate's result? I mean if I have 6 files located at /backup/
and 2 at /home/alex/files/
I would like to set, or ask if they what to get all the files from the most common folder, /backup/
!
This is meant when I have more than X files (ex: 10), because sometimes I can get up to hundreds of results and I can't go 1 by 1!
Solution
I'd use awk and read.
# list of files in temp file
choices=$(mktemp -t choices.XXXXX)
find . -name "file.txt") > $choices
# choices with number prefix
cat $choices | awk '{print "[" NR "]" $0}'
# prompt
echo "Choose one"
read num
# find choice
choice=$( cat $choices | awk "{if (NR==$num){print \$0}}" )
echo "You choose $choice"
OTHER TIPS
If you are using bash, you can use the built-in arrays like:
# Get all the files
files=`find . -name "file.txt"`
# Put them into an array
declare -a afiles
afiles=( ${files} )
# Output filenames
for (( i = 0; i < ${#afiles[@]}; i += 1 ));
do
printf "[%d] %s\n" ${i} ${afiles[$i]}
done
(The declare is not neccessary but IMHO it is a good comment saying that afiles
is an array.)
Using arrays has the advantage that you can access the filename after the user entered some number with ${afiles[${number}]}
.
For your update
#paths in order
find . -name '*.txt' | awk '{gsub(/\/[^/]*$/,"");path[$0]+=1} END {for (i in path) print path[i]" "i}' | sort -rg | cut -d ' ' -f 2
Use what has already been posted for the rest