1

I am using Cygwin as Linux shell, I have following contents in my current working directory:

Files :

Abc.dat 
123.dat 
456.dat

Directories:

W_Abc_w 
W_123_w 
W_456_w

Now I want to copy files as below:

Abc.dat -> W_Abc_w 
123.dat -> W_123_w 
456.dat -> W_456_w

How to achieve this in a single line linux command? I need a generic solution which can be used for similar cases in future...

Destination directory always exists, but number of characters in file name will vary. Destination directory name will always contain the file name of file to be copied along with other extra characters. Destination directory names have unique pattern eg. Abc_sa_file_name_1 second directory name will be Abc_sa_file_name_2. File names also has pattern e.g kim_1. Kim_2 .
I will be moving or copying file kim_1 to Abc_sa_kim_1_1. I wish to operate complete pattern in one command.

10
  • In a single command you mean without for loop? Commented Nov 20, 2019 at 18:15
  • Right, may be using system variables Commented Nov 20, 2019 at 18:18
  • That one very specific result, or by following some pattern (that you should describe)? Commented Nov 20, 2019 at 18:27
  • Using the patterns and variables. Commented Nov 20, 2019 at 18:32
  • Do your filenames always match ???.dat? Will the destination directories always exist? Commented Nov 20, 2019 at 18:38

1 Answer 1

3

In one command (line):

cp Abc.dat W_Abc_w/; cp 123.dat W_123_w/; cp 456.dat W_456_w/

The trailing slashes are not required, but a habit to indicate that the intention is to put the file into a destination directory not as a new file.

As a generic loop with a pattern:

for f in ???.dat
do
  [ -d W_"${f%.dat}"_w ] && cp -- "$f" W_"${f%.dat}"_w
done

This picks up every filename that has three characters followed by .dat and copies them into the correspondingly-named directory, if that directory already exists. The filename expansion inside the cp command strips off the trailing .dat.

If you were interested in a command-line approach that does not use a loop -- but also moves the files instead of copies them -- you could use zsh:

autoload zmv
zmv '(???).dat' 'W_$1_w'
4
  • Last one seems good, I will try it and let you know what happened! Thanks Commented Nov 20, 2019 at 18:44
  • @VikramTidake I believe that mmv is available for Cygwin, providing shell-independent functionality similar to zmv if you prefer ex. mmv '???.dat' 'W_#1#2#3_w/' - it has a -c option (and possibly a mcp binary) to copy rather than move. Commented Nov 20, 2019 at 20:00
  • How one can perform this operation with <find> command? Commented Nov 29, 2019 at 14:32
  • Vikram, if your requirement is to use "find", please make that explicit in your question. I will re-add the "find" tag. Thank you. Commented Nov 30, 2019 at 14:15

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.