A. Archer
A. Archer

Reputation: 85

Rename files to unique names and move them into a single destination directory

i have 100s of directories with same filename of content.html along with other files.

I am trying to copy all these content.html files under 1 directory, but since they have same name, it overwrites each other

so how can i rename and move all these under 1 directory

Eg:

./0BD3D9D2-F8B1-4472-95C2-13319650A45C:
card.png  content.html    note.xhtml  quickLook.png   snippet.txt

./0EA34DB4-CD56-42BE-91DA-F631E44FB6E0:
card.png  content.html    note.xhtml  quickLook.png   related     snippet.txt

./1A33F29E-3938-4C2F-BA99-6B98FD045742:
card.png  content.html    note.xhtml  quickLook.png   snippet.txt

command i tried:

  1. rename content.html to content

    find . -type f | grep content.html | while read f; do mv $f ${f/.html/}; done

  2. append number to filename "content" to make it unique

    find . -type f | grep content | while read f; do i=1; echo mv $f $f$i.html; i=i+1; done

MacBook-Pro$ find . -type f | grep content | while read f; do i=1; echo mv $f $f$i.html; i=i+1; done

mv ./0BD3D9D2-F8B1-4472-95C2-13319650A45C/content ./0BD3D9D2-F8B1-4472-95C2-13319650A45C/content1.html

mv ./0EA34DB4-CD56-42BE-91DA-F631E44FB6E0/content ./0EA34DB4-CD56-42BE-91DA-F631E44FB6E0/content1.html
mv ./1A33F29E-3938-4C2F-BA99-6B98FD045742/content ./1A33F29E-3938-4C2F-BA99-6B98FD045742/content1.html
  1. once above step is successful, i should be able do this to achieve my desired output:

    find . -type f | grep content | while read f; do mv $f ../; done

however, i am sure i can do this in 1 step command and also my step 2 is not working (incrementing i)

any idea why step2 is not working??

Upvotes: 0

Views: 1329

Answers (5)

codeforester
codeforester

Reputation: 42999

You can use shopt -s globstar to grab all content.html files recursively and then use a loop to rename them:

#!/bin/bash

set -o globstar
counter=0
dest_dir=/path/to/destination
for f in **/content.html; do  # pick up all content.html files
  [[ -f "$f" ]] || continue   # skip if not a regular file
  mv "$f" "$dest_dir/content_$((++counter).html"
done

Upvotes: 0

Anup
Anup

Reputation: 99

I'd use something like this:

find . -type f -name 'test' | awk 'BEGIN{ cnt=0 }{ printf "mv %s ./output-dir/content_%03d.txt\n", $0, cnt++ }' | bash;

You can replace ./output-dir/ with your destination directory

Example:

[root@sl7-o2 test]# ls -R
.:
1  2  3  output-dir

./1:
test

./2:
test

./3:
test

./output-dir:

[root@sl7-o2 test]# find . -type f -name 'test' | awk 'BEGIN{ cnt=0 }{ printf "mv %s ./output-dir/content_%03d.txt\n", $0, cnt++ }' | bash;

[root@sl7-o2 test]# ls ./output-dir/
content_000.txt  content_001.txt  content_002.txt

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

bash script:

#!/bin/bash    
find . -type f -name content.html | while IFS= read -r f; do
    name=$(basename $f)
    ((++i))
    mv "$f" "for_content/${name%.*}$i.html"
done

replace for_content with your destination folder name

Upvotes: 2

Raman Sailopal
Raman Sailopal

Reputation: 12867

The inode of the of the files should be unique and so you could use the following:

find $(pwd) -name "content.html" -printf %f" "%i" "%p"\n" | awk '{ system("mv "$3" <directorytomoveto>"$2$1) }'  

Upvotes: 0

sjsam
sjsam

Reputation: 21955

Suppose in your base directory, you create a folder named final for storing content.html files, then do something like below

find . -path ./final -prune -o -name "content.html" -print0 |
while read -r -d '' name
do 
mv "$name" "./final/content$(mktemp -u XXXX).html"
# mktemp with -u option just creates random characters, or it is just a dry run
done

At the end you'll get all the content.html files under ./final folder in the format contentXXXX.html where XXXX are random characters.


Note:-path ./final -prune -o in find prevents it from descending to our results folder.

Upvotes: 1

Related Questions