Reputation: 23
I have a file input.txt
that looks as follows.
abas_1.txt
abas_2.txt
abas_3.txt
1fgh.txt
3ghl_1.txt
3ghl_2.txt
I have a folder ff
. The filenames of this folder are abas.txt
, 1fgh.txt
, 3ghl.txt
. Based on the input file, I would like to create and rename the multiple copies in ff folder.
For example in the input file, abas
has three copies. In the ff
folder, I need to create the three copies of abas.txt
and rename it as abas_1.txt
, abas_2.txt
, abas_3.txt
. No need to copy and rename 1fgh.txt
in ff folder.
Your valuable suggestions would be appreciated.
Upvotes: 2
Views: 130
Reputation: 596
If you could change the format of input.txt
, I suggest you adjust it in order to make your task easier. If not, here is my solution:
#!/bin/bash
SRC_DIR=/path/to/ff
INPUT=/path/to/input.txt
BACKUP_DIR=/path/to/backup
for cand in `ls $SRC_DIR`; do
grep "^${cand%.*}_" $INPUT | while read new
do
cp -fv $SRC_DIR/$cand $BACKUP_DIR/$new
done
done
Upvotes: 0
Reputation: 4496
Try this one
#!/bin/bash
while read newFileName;do
#split the string by _ delimiter
arr=(${newFileName//_/ })
extension="${newFileName##*.}"
fileToCopy="${arr[0]}.$extension"
#check for empty : '1fgh.txt' case
if [ -n "${arr[1]}" ]; then
#check if file exists
if [ -f $fileToCopy ];then
echo "copying $fileToCopy -> $newFileName"
cp "$fileToCopy" "$newFileName"
#else
# echo "File $fileToCopy does not exist, so it can't be copied"
fi
fi
done
You can call your script like this:
cat input.txt | ./script.sh
Upvotes: 0
Reputation: 46873
You can try something like this (to be run from within your folder ff
):
#!/bin/bash
while IFS= read -r fn; do
[[ $fn =~ ^(.+)_[[:digit:]]+\.([^\.]+)$ ]] || continue
fn_orig=${BASH_REMATCH[1]}.${BASH_REMATCH[2]}
echo cp -nv -- "$fn_orig" "$fn"
done < input.txt
Remove the echo
if you're happy with it.
If you don't want to run from within the folder ff
, just replace the line
echo cp -nv -- "$fn_orig" "$fn"
with
echo cp -nv -- "ff/$fn_orig" "ff/$fn"
The -n
option to cp
so as to not overwrite existing files, and the -v
option to be verbose. The --
tells cp
that there are no more options beyond this point, so that it will not be confused if one of the files starts with a hyphen.
Upvotes: 1
Reputation: 5424
using for
and grep
:
#!/bin/bash
for i in $(ls)
do
x=$(echo $i | sed 's/^\(.*\)\..*/\1/')"_"
for j in $(grep $x in)
do
cp -n $i $j
done
done
Upvotes: 0