# Ubuntu – Copying certain files by partially matching their names to a list within a text file

command line

I have a directory with files with string names that all start out with 5 numbers (i.e. 12345_a_b, 23456_s_a) and I have a text file within the same directory that has a list of file names named in the same way, however only the numbers match and not anything after the underscore (i.e 12345_q_p, 23456_p_l). I want to copy files in the current directory into a new one, but only those where the first 5 numbers in the name of the file match the first 5 numbers of each filename in the text file, ignoring everything that comes after. It seems like I can use xargs but I'm not sure how to match names partially. Can anyone help?

Iterate over the lines with _ as the IFS, get the desired first portion containing digits, and the copy the files starting with those digits:

shopt -s nullglob
while IFS=_ read -r i _; do [[ $i =~ ^[0-9]{5}$ ]] && echo cp -it dest/ "${i}"*; done <file.txt  Expanded: #!/bin/bash shopt -s nullglob ##Expands to null string if no match while doing glob expansion, ##rather than the literal while IFS=_ read -r i _; do ##Iterate over the lines of file.txt, ##with _ as the IFS i.e. word splitting ##happens on each _ only, variable i ##will contain the digits at start; _ is a ##throwaway variable containing the rest [[$i =~ ^[0-9]{5}$]] \ ##Check if the variable contains only 5 digits && echo cp -it /destination/ "${i}"*  ##if so, copy the relevant files starting with those digits
done <file.txt


Replace file.txt with the actual source file, and /destination/ with your actual destination directory. Here echo is included to do the dry-run; if satisfied with the commands to be run, just get rid of echo:

shopt -s nullglob
while IFS=_ read -r i _; do [[ $i =~ ^[0-9]{5}$ ]] && cp -it dest/ "\${i}"*; done <file.txt