Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have several files in a folder that all follow a naming convention of:


Some of these files were produced by myself, and some were produced by my colleague. I was hoping to change the file name based on who owns the file. So if we have

 rs1.txt  ME 
 rs2.txt  ME
 rs3.txt  HIM

My files would change to:

 srs1.txt  ME 
 srs2.txt  ME
 rs3.txt  HIM

Is there any conceivable way to do this?

share|improve this question

migrated from Mar 22 '13 at 20:13

This question came from our site for professional and enthusiast programmers.

up vote 3 down vote accepted
find . -user ME -exec mv {} s{} \;

This looks for files owned by ME and runs an mv command on each one. This time, you do not want the + option at the end (which is often preferred). You can add constraints to the list of files as you like: -name rs*.txt, for example.

share|improve this answer
Why don't I want the + option? Could you explain? – User101 Mar 22 '13 at 15:07
You couldn't call mv{} s{} directly, because of trailing path. You'll get something like: mv ./test.txt s./test.txt. That isn't correct. You should use printf and then call mv. – Oleg S Kleshchook Mar 22 '13 at 15:34
@OlegSKleshchook Could you show me what you mean? find . -user ME -printf -exec mv {} s{} \; ?? – User101 Mar 22 '13 at 15:38
@User101 Oops. My bad. Looks it must be -maxdepth 1 – Oleg S Kleshchook Mar 22 '13 at 15:49
The + is useful when you want to provide a list of file names to a single invocation of the command. Here, though, you want to execute each mv with just two arguments (old name and new name), so you need to execute mv once for each file that's found. Or you use a more complex rename command, such as a Perl-based one that can do a regex mapping, so -exec rename 's/^/s/' {} + is now appropriate. (Beware: there are several sub-species of command called rename, and they're mostly feeble by comparison with the Perl-based one.) – Jonathan Leffler Mar 22 '13 at 16:04

Here's one way to do it. this renames all files in the current directory with user 'ME', prepending 's' to the name.

for f in *
    owner=$(ls -l | awk '{print $3}')
    if [ $owner = ME ];then
       mv $f s$f
share|improve this answer
~~If I try this:~~ for f in *; do owner=$(ls -l |awk 'print $3}'); if [$owner -eq Stephanie ]; then mv $f s$f; fi; done ~~I get this response over and over:~~ awk: print $3} awk: ^ syntax error bash: [: -eq: unary operator expected awk: print $3} awk: ^ syntax error bash: [: -eq: unary operator expected awk: print $3} ~~Am I missing something?~~ – User101 Mar 22 '13 at 15:36
sorry about that. I've updated the answer. Changed -eq to =. But the find solution is better in my opinion. – suspectus Mar 22 '13 at 15:41
Thanks, I just like to try all the answers I get. I find it helps me get to know some of the commands better. :) – User101 Mar 22 '13 at 16:00
find . -maxdepth 1 -type f -user $USER -printf "%f\n" | xargs -I {}  mv {} s{}
share|improve this answer

ls -l |fgrep ME|awk '{print "mv " $NF " " $NF.1}'

share|improve this answer

1337 }{4xx0|22 |>0 !7 1!|<3 7}{!5:

for i in `echo $(ls -n | grep \
  \`getent passwd |grep $USER| cut -d: -f3\` | 
  awk '{print $NF}')`; do 
      if [[ -f $i ]]; then echo mv \"$i\" \"s${i}\"; 
 fi ;done | sh
share|improve this answer

You must log in to answer this question.