Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I rename all files within a folder with the first word of their content? For example if a.txt contains “Unix is an OS” in its first line then a.txt should be renamed to Unix.txt

share|improve this question
    
Please correct title into something like "How do I rename multiple file in unix?" –  Johan May 14 '11 at 9:55
    
Missed that on this site, I thought I did not have enought rep here... –  Johan May 14 '11 at 11:11
    
That title is also too misleading. It leaves out the core detail that the new name must be based on file content. –  jmtd May 20 '11 at 12:41

6 Answers 6

Try this:

for f in *.txt; do d="$(head -1 "$f" | awk '{print $1}').txt"; if [ ! -f "$d" ]; then mv "$f" "$d"; else echo "File '$d' already exists! Skiped '$f'"; fi; done

or more long variant (as script):

#!/bin/sh
for f in *.txt; do
    d="$(head -1 "$f" | awk '{print $1}').txt"
    if [ ! -f "$d" ]; then
        mv "$f" "$d"
    else
        echo "File '$d' already exists! Skiped '$f'"
    fi
done

In case when destination file exists this one-liner skips it.

share|improve this answer
5  
I'd simplify head -1 "$f" | awk '{print $1}' to <"$f" awk {print $1; exit}. –  Gilles May 14 '11 at 11:09

Here is my approach.

#!/bin/bash
for file in *; 
do
    if [[ -f $file ]]; 
    then
        # cut word by single white space
        fileword=$(head -n1 "$file" | cut -f1 -d" ");
        # Everything after first dot is considered as extention
        ext=$(echo $file | sed 's/.*\.\(.*\)/.\1/g')
        [ "$file" != "$fileword" ] && $(mv  "$file"  "$fileword$ext")
    fi;
done
share|improve this answer

Use this oneliner

for i in *; do if [ ! -f $i ]; then echo "skipping $i"; else newname=`head -1 $i | sed 's/^\s*\([a-zA-Z0-9]\+\).*$/\1/'`; [ -n "$newname" ] && mv -i $i $newname.txt || echo "error at: $i"; fi; done

This will replace all files with the first word in that file + .txt. I defined first word to be the first occurrence of [a-zA-Z0-9]+, discarding leading white spaces.
Disclaimer: Please just use it if you are sure that there is a first word on line one in each file! Otherwise you might experience unexpected results ;-)

share|improve this answer
4  
Gah! Don't parse the output of ls! The shell already knows how to act on all the files in a directory, it's spelled *. –  Gilles May 14 '11 at 11:07
for i in *.txt
do
d="$(head -1 "$i" | cut -d " " -f1).txt";
mv "$i" "$d"
done
share|improve this answer
    
The character after the first word could be different than space (a comma for example) –  Philippe Blayo Nov 19 '12 at 18:40
for i in *.txt; do mv "$i" "$(head -1 "$i")".txt; done
share|improve this answer
2  
First word, not first line. –  Gilles Jun 14 '11 at 9:16

On your own risk: :)

find -exec echo -n mv {} " " ";" -exec sed '1s/ .*//;q' {} ";" > tmp.sh && bash tmp.sh

This works with easy filenames, containing easy words. A file "O'Reilly" containing as first word "Eto'o" will fail. Miserably.

share|improve this answer
    
You're missing a step of quoting. What if there's a file called some'thing, or if the first word is D'oh? –  Gilles Jun 14 '11 at 9:18
    
Yes, I see. How would you do it? Not at all - choose a different approach? –  user unknown Jun 14 '11 at 20:00
    
It's technically possible to generate a shell script, but it's calling for trouble. You “just” need to get the quoting right. There's no call for it here, just extract the first word and call mv right there, like the other answers. You can keep your sed command, it's a fine way to extract the first word. –  Gilles Jun 15 '11 at 8:04
    
In praxis, I would, if I used this approach, use two commands - ... > tmp.sh, and review tmp.sh manually. Then invoke bash tmp.sh. With a lot of funky filenames, I wouldn't do it at all. But one or two manual corrections would be fine in 100 files. In about 1000 files, a manual review would start becoming work. –  user unknown Jun 15 '11 at 17:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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