I've got a complicated challange. I'm not very practical of linux and script but I need to solve a problem. I've got a file list.txt containing two column in the first there is the name of the objects and in the second there is variable. Now I want used this information to copy a specific files in specif directories. For example:

The working directory is this: /nfs/BioGPSDB/pockets/MD/fixed/1/

This is the file /home/tommaso/Desktop/list.txt:

121p1_004_______________  GCP
13gs1_001_______________  SAS
1am42_003_______________  GNP
1bmq1_003_______________  MNO

In the working directory show below there are a lot of directory and the name of some of this directories is correleted to the first 5 characters of name of the object present in the first column of the file "list.txt". For example: 1j4r3, 1t403, 121p1, 1sdr4, 1bmq1 ecc...

In each of this directory there are a lot of files. I need, for each line of the file "list.txt" use the first column to select the direcoty, enter on this directory, select the file of interest and copy this in another direcory (/home/tommaso/Desktop/pdb_files). The file of interest is called like the variable reported in the second column of the file "list.txt". Example:

directory: /nfs/BioGPSDB/pockets/MD/fixed/1/121p1
File of interest: "GCP_?.pdb" where "?" is one character (letter or number)
Final directory: /home/tommaso/Desktop/pdb_files

So in the end in the directory /home/tommaso/Desktop/pdb_files I must have all files like this: GCP_?.pdb, SAS_?.pdb, GNP_?.pdb, MNO_?.pdb ecc..

So the script should read the list.txt file and for each directory named as the first 5 characters in each row of the first column it should copy the file named as the variable in the second column with extension "_?.pdb" in a final directory where all files will be present.

I hope to have been clear enough and I hope to find someone willing to help me because I don’t know where to start!


You should be able to do that using something along these lines:

cd /nfs/BioGPSDB/pockets/MD/fixed/1/
while IFS= read -r line
  echo cp -i -- "${line:0:5}/${line##* }"_?.pdb /home/tommaso/Desktop/pdb_files/
done < /home/tommaso/Desktop/list.txt

Remove the echo to actually copy your files when satisfied with the printed cp commands.

Assuming you only have one file matching the ${line##* }"_?.pdb pattern in each directory, you can also name it in a way that matches the _?.pdb suffix shown in your question by changing the cp command line into:

cp -i -- "${line:0:5}/${line##* }"_?.pdb \
  "/home/tommaso/Desktop/pdb_files/${line##* }_?.pdb"

The -i option to cp instructs it to ask before overwriting files in the destination directory; it is not essential, based on your requirements, but it makes sense when files coming from distinct directories are copied/moved to a single directory.

This script assumes that each file name fragment is preceded by one or more spaces in list.txt. Replace the space in ${line##* } with the character that immediately precedes the file name fragments if appropriate.

The ${line:0:5} kind of expansion—which reads "substitute with the five-characters substring of the line variable that starts at index 0 (the first character)"—is supported in several shells (bash, ksh93, zsh, busybox ash, ...), but is not part of POSIX and notably not available in dash.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.