It seems that you're using an outdated browser. Some things may not work as they should (or don't work at all).
We suggest you upgrade newer and better browser like: Chrome, Firefox, Internet Explorer or Opera

×
Long story short: I am now the proud owner of hundreds of thousands of numbered text files. Do you know of an easy way to give the files the names of the first line of text so the file names will better represent the document contents?

Thanks y'all!
This question / problem has been solved by Barefoot_Monkeyimage
#!/bin/sh
for i in *
do
text = `head -n1 $i`
mv $i "$text.txt"
done
Post edited April 27, 2012 by Qbix
for i in *.txt; do mv "$i" "`head -n 1 "$i"`.txt"; done
Yeah, I'd definitely write some sort of script to do that. Of course, you have to take into account that the first line of text may contain characters that cannot legally be part of a file name.
avatar
Qbix: #!/bin/sh
for i in *
do
text = `head -n1 $i`
mv $i "$text.txt"
done
Interesting, whenever I've needed to do that I've always just used xargs. And I'd probably make use of sed to ensure that the filename ended up being something of reasonable length.
avatar
Wishbone: Yeah, I'd definitely write some sort of script to do that. Of course, you have to take into account that the first line of text may contain characters that cannot legally be part of a file name.
If it's genuinely a text document in use by a Canadian, then it shouldn't be the case.

Throwing in something like this: sed 's/[!@#\$%^&*()]//g' to a pipe would clear most of that up. Which is probably why I end up using xargs so often as it allows me to do stuff like that without too much trouble.
Post edited April 27, 2012 by hedwards
avatar
Wishbone: Yeah, I'd definitely write some sort of script to do that.
That, or hire a couple thousand poor Chinese farmers to rename the files manually. :)
Your best bet is to find yourself a bash shell and copy&paste Sude's command.
avatar
Wishbone: Yeah, I'd definitely write some sort of script to do that.
avatar
timppu: That, or hire a couple thousand poor Chinese farmers to rename the files manually. :)
Heh, if he wants that, I could probably find somebody to do it for him. Around here labor is dirt cheap and they could actually make some nice money without screwing Jimmy over.
Combining Sude's and hedwards's advice (and reading up on what the forbidden filename characters for Windows are), try this:
for i in *.txt; do mv "$i" "`head -n 1 "$i" | sed 's/["/\\:*?<>|]//g'`.txt"; done

You'll need to paste that whole link into a bash shell and press Enter. Perhaps install cygwin and use that.
Post edited April 27, 2012 by Barefoot_Monkey
avatar
Barefoot_Monkey: Combining Sude's and hedwards's advice, try this:
for i in *.txt; do mv "$i" "`head -n 1 "$i" | sed 's/["/\\:*?<>|]//g`.txt"; done

You'll need to paste that whole link into a bash shell and press Enter. Perhaps install cygwin and use that.
That's missing single quote after sed
for i in *.txt; do mv "$i" "`head -n 1 "$i" | sed 's/["/\\:*?<>|]//g'`.txt"; done
Did a Google search for "batch bulk rename utility" which returned several utilities for doing what you need. This one is free and the first returned. Never used it but might be an easy solution without the need for coding yourself. Might try it or one of several other batch renaming utilities available.
In windows (7) .CMD:
Save below text as something.cmd and replace variables with paths/file lengths you want.
I suck at scripting, but that worked for me.

Good luck :)

-----------------

setlocal ENABLEDELAYEDEXPANSION
echo off

::variables
set filenamelength=20
set originaldirectory=%userprofile%\Documents\test\original\
set backupdirectory=%userprofile%\Documents\test\backup\
set fileext=txt

::start
FOR /R "%originaldirectory%" %%I IN (*.%fileext%) DO (
SET oldfilename=%%I
FOR /F "usebackq delims=" %%G IN ("%%I") DO (
SET newfilename=%%G
SET newfilename=!newfilename:~0,%filenamelength%!
copy "!oldfilename!" "%backupdirectory%!newfilename!.%fileext%"
)
)

pause
:end
avatar
Sude: That's missing single quote after sed
for i in *.txt; do mv "$i" "`head -n 1 "$i" | sed 's/["/\\:*?<>|]//g'`.txt"; done
Thanks. Edited my post with that correction.
Another solution, for Windows Powershell.

Get-ChildItem *txt | ForEach-Object -Process { $a = Get-Content $_ -totalcount 1; $a = $a -replace '["/\\:*?<>|]',''; if($a.length -gt 32) { $a = $a.substring(0,32) }; Rename-Item $_ $a'.txt' }

A tad longer than the bash solutions, but I'm very much a novice with powershell so I'm sure it could be shortened a bit.
Replace both instances of "32" with your desired filename length.
avatar
Qbix: snip
avatar
Sude: snip
avatar
Barefoot_Monkey: snip
avatar
Sude: snip
avatar
benjiir: snip
avatar
Miaghstir: snip
I am admittedly more than a bit rusty so I really appreciate the good looking solutions you have provided. I'll give some of those variations a shot shortly. Thank you all.



avatar
Stuff: Did a Google search for "batch bulk rename utility" which returned several utilities for doing what you need. This one is free and the first returned. Never used it but might be an easy solution without the need for coding yourself. Might try it or one of several other batch renaming utilities available.
Hmm, that utility did show up in my search as well but I didn't get the feeling it could do what I needed. I'll fire up Windows in a bit and take a closer look. Thanks.