10

Suppose I have a folder containing some files and some folders(files can be of any type). And I want to move/copy some of those files and folders using mv/cp command. Is there any way, such that I could select some of them randomly, just as we do selection using the Ctrl key, and do move/copy using terminal? I can't use neither wildcard, nor the regular expression, as I want to select files of different types, and their names have small amount of similarities.

4
  • 3
    You might want to provide more info. What kind of similarity files have ? Jul 20, 2016 at 9:39
  • 2
    Even if you can't use regular expressions or wildcards, you can maybe take advantage of similarity and braces to expand arguments. In bash anyways if you have file1, file2, file3 as in one of the answers below, you can just use cp -t /dest/ file{1,2,3} or for ranges cp -t /dest/ file{1..3}. It works for non-numeric args and combinations too, e.g. cp -t /dest/ f{ile,ly}.{csv,txt} executes cp -t /dest/ file.txt file.csv fly.txt fly.csv. Be careful with overwriting things if position is important, but I find them useful.
    – neocpp
    Jul 20, 2016 at 12:12
  • Why do you need this? Why not using the file manager as you describe? The shell tools tries to be the less ambiguous as possible.
    – Braiam
    Jul 20, 2016 at 14:55
  • We all know we can select random files and folders under a folder using the Ctrl key. I just want to know whether we can implement a similar technique while using Linux terminal
    – MikhilMC
    Jul 20, 2016 at 16:50

4 Answers 4

14

If you want to move or copy all of the files to the same directory, you can use the -t option of cp or mv, but this will mean that you have to type/supply each filename as an argument. It works in the following manner, with as many files as arguments as you like:

cp -t /destination/directory/ file1 file2 file3

or

mv -t /destination/directory/ file1 file2 file3

This is quite laborious, but typing the file names can be made easier using Bash's tab completion.

Alternatively the following bash script will find all the files in a directory, given as the first argument, and copy the selected files into the destination directory, given as the second argument.

It checks each file and asks whether you want to copy that file. At the end of file selection it shows a list of selected files and asks if you want to copy them to the destination directory:

#!/bin/bash
directory=$1
destination=$2
selected_files=()
for f in ${directory}/*
do
  if [[ -f $f ]]
  then
    while true
    do
      read -p "Would you like to copy ${f}? y/n: " choice
      case $choice in
        y|Y) selected_files+=("$f");
             break ;;
        n|N) echo "${f} will not be copied.";
             break ;;
        *) echo "Invalid choice, enter y/n: " ;;
      esac
    done
  fi
done
echo "The following files will be copied to ${destination}."
for file in "${selected_files[@]}"
do
  echo "$file"
done
while true
do
  read -p "Are these the correct files? y/n: " confirm
  case $confirm in
    y|Y) break ;;
    n|N) echo "Exiting filechooser"; exit 1 ;;
    *) echo "Invalid choice, enter y/n: " ;;
  esac
done
cp -t "$destination" "${selected_files[@]}"

Be warned that there's no error checking in this script about whether the destination directory exists, or that you've input the correct arguments.

5

Here's a script that selects a random set of files/directories to be copied. It can deal with arbitrary file names, even those containing newlines and spaces. Save the script as ~/bin/randomCopy.sh, make it executable (chmod a+x ~/bin/randomCopy.sh) and then run it, giving it the source directory as the first argument, the target directory as the second and the number of files/dirs (the script doesn't differentiate between files and directories, as you requested) to be copied. For example, to copy 5 random files or directories from /foo to /bar:

randomCopy.sh /foo /bar 5

The script:

#!/bin/bash

if [ $# -lt 3 ]; then
        cat<<EOF 
This script needs at least 3 arguments: the source directory, the
target directory and the number of files/dirs to be copied. For example:

    $0 /from /to 5

EOF
        exit
fi 

sourceDir="$1"
targetDir="$2"
number="$3"

## Collect all file and directory names. The globstar
## bash option lets ** match all files and directories
## recursively
shopt -s globstar
dirsAndFiles=( ** )

## Get $num random numbers from 0 until
## the number of files and dirs found. This
## will let us take a random selection.
limit=$((${#dirsAndFiles[@]}-1))  
numbers=$(shuf -i 0-"$limit" -n "$number")

for num in $numbers; do
    cp -rv "${dirsAndFiles[$num]}" "$targetDir"
done

Note that this will overwrite existing files if any with the same file name exist in the target directory.

1

Maybe try using something like Midnight Commander? It is a console application that provides similar features to the graphical Nautilus File Manager.

0

Recently I found out an effective solution for this problem using xargs.

`xargs cp
 file1
 file2
 .....
 .....
 <path of the destination folder>`

Then type Ctrl + C. This will work for sure. I've tested it. By this method we can select files just like using Ctrl button in the graphics mode, and do copy/move/remove.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .