Script to rename a large number of files using the text in each file to rename
I am trying to devise a solution to rename a large collection of files so that the text in line 3 of each file is the new filename. These files all have the same structure. My scripting ability is poor so I am hoping this problem has been approached before by others so I don't need to invent a new wheel? I've been consulting some sed and awk tutorials but not finding a solution there.
These are HTML files and specifically line 3 of each file looks like this.
<TITLE>DATA POPULATION 'CODE on group 1234 by THING'</TITLE>
I want to grab everything between the single quotes and use that text to rename the file with that text as the filename.
Can anyone point me down the right path to approach this task? The notion of renaming these one at a time would just be murder.
Thanks for reading and pondering this problem.
shell-script rename
New contributor
add a comment |
I am trying to devise a solution to rename a large collection of files so that the text in line 3 of each file is the new filename. These files all have the same structure. My scripting ability is poor so I am hoping this problem has been approached before by others so I don't need to invent a new wheel? I've been consulting some sed and awk tutorials but not finding a solution there.
These are HTML files and specifically line 3 of each file looks like this.
<TITLE>DATA POPULATION 'CODE on group 1234 by THING'</TITLE>
I want to grab everything between the single quotes and use that text to rename the file with that text as the filename.
Can anyone point me down the right path to approach this task? The notion of renaming these one at a time would just be murder.
Thanks for reading and pondering this problem.
shell-script rename
New contributor
add a comment |
I am trying to devise a solution to rename a large collection of files so that the text in line 3 of each file is the new filename. These files all have the same structure. My scripting ability is poor so I am hoping this problem has been approached before by others so I don't need to invent a new wheel? I've been consulting some sed and awk tutorials but not finding a solution there.
These are HTML files and specifically line 3 of each file looks like this.
<TITLE>DATA POPULATION 'CODE on group 1234 by THING'</TITLE>
I want to grab everything between the single quotes and use that text to rename the file with that text as the filename.
Can anyone point me down the right path to approach this task? The notion of renaming these one at a time would just be murder.
Thanks for reading and pondering this problem.
shell-script rename
New contributor
I am trying to devise a solution to rename a large collection of files so that the text in line 3 of each file is the new filename. These files all have the same structure. My scripting ability is poor so I am hoping this problem has been approached before by others so I don't need to invent a new wheel? I've been consulting some sed and awk tutorials but not finding a solution there.
These are HTML files and specifically line 3 of each file looks like this.
<TITLE>DATA POPULATION 'CODE on group 1234 by THING'</TITLE>
I want to grab everything between the single quotes and use that text to rename the file with that text as the filename.
Can anyone point me down the right path to approach this task? The notion of renaming these one at a time would just be murder.
Thanks for reading and pondering this problem.
shell-script rename
shell-script rename
New contributor
New contributor
edited 8 mins ago
Stéphane Chazelas
304k57570927
304k57570927
New contributor
asked 2 hours ago
Daniel CrossDaniel Cross
61
61
New contributor
New contributor
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
$ awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "t" 'mv {1} {2}'
awk
iterate over all files in the location. We define the '
as the field separator. Whenever it reaches the third line and there are more than 2 fields (which should be if we have two '
) it prints out the filename and the second field (which is the part between the first two '
) delimited by a tab. Then it skipes to the next file.
The result is piped to parallel
. parallel
execute the mv
command by replacing {1}
and {2}
with values given in the columns from the awk
result.
Some notes:
nextfile
is not available in allawk
versions
whitespaces in a filename is never a good idea. You could replace them by an underscore if you change the
awk
command like this:
awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt
- You should move or copy your new filenames to another folder. I'm not sure how
awk
will react if new files appear in the same folder during runtime.
add a comment |
for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done
It will search all the files in the current directory and will move this file to the new one.
add a comment |
for src in *.html; do
{ read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
mv -- "$src" "$dst.html"
done
add a comment |
I would do such a thing in perl instead of putting together some slow and fragile tangle of subshells:
perl -e 'while(<>){
sub no_rename { print "rename @_n" }
next unless $. == 3;
if(my ($f) = /DATA POPULATION +'''(.*?)'''/){
$f =~ s/[^w]/_/g;
no_rename $ARGV, $f or warn "rename $ARGV, $f: $!n";
}
close ARGV
}' files ...
You'll have to change no_rename
to rename
to make it actually do it, instead of showing it.
Sorry for the ugly '''
; if you put that in a script file instead of one-liner, that should be simply:
/DATA POPULATION +'(.*?)'/
If you really want to create filenames with spaces, also add a s
after the w
in the s///g
expression (and similar for other characters that could go in the filename -- by default, the script will replace everything but letters and digits with an underscore).
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Daniel Cross is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f498718%2fscript-to-rename-a-large-number-of-files-using-the-text-in-each-file-to-rename%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
$ awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "t" 'mv {1} {2}'
awk
iterate over all files in the location. We define the '
as the field separator. Whenever it reaches the third line and there are more than 2 fields (which should be if we have two '
) it prints out the filename and the second field (which is the part between the first two '
) delimited by a tab. Then it skipes to the next file.
The result is piped to parallel
. parallel
execute the mv
command by replacing {1}
and {2}
with values given in the columns from the awk
result.
Some notes:
nextfile
is not available in allawk
versions
whitespaces in a filename is never a good idea. You could replace them by an underscore if you change the
awk
command like this:
awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt
- You should move or copy your new filenames to another folder. I'm not sure how
awk
will react if new files appear in the same folder during runtime.
add a comment |
$ awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "t" 'mv {1} {2}'
awk
iterate over all files in the location. We define the '
as the field separator. Whenever it reaches the third line and there are more than 2 fields (which should be if we have two '
) it prints out the filename and the second field (which is the part between the first two '
) delimited by a tab. Then it skipes to the next file.
The result is piped to parallel
. parallel
execute the mv
command by replacing {1}
and {2}
with values given in the columns from the awk
result.
Some notes:
nextfile
is not available in allawk
versions
whitespaces in a filename is never a good idea. You could replace them by an underscore if you change the
awk
command like this:
awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt
- You should move or copy your new filenames to another folder. I'm not sure how
awk
will react if new files appear in the same folder during runtime.
add a comment |
$ awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "t" 'mv {1} {2}'
awk
iterate over all files in the location. We define the '
as the field separator. Whenever it reaches the third line and there are more than 2 fields (which should be if we have two '
) it prints out the filename and the second field (which is the part between the first two '
) delimited by a tab. Then it skipes to the next file.
The result is piped to parallel
. parallel
execute the mv
command by replacing {1}
and {2}
with values given in the columns from the awk
result.
Some notes:
nextfile
is not available in allawk
versions
whitespaces in a filename is never a good idea. You could replace them by an underscore if you change the
awk
command like this:
awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt
- You should move or copy your new filenames to another folder. I'm not sure how
awk
will react if new files appear in the same folder during runtime.
$ awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "t" 'mv {1} {2}'
awk
iterate over all files in the location. We define the '
as the field separator. Whenever it reaches the third line and there are more than 2 fields (which should be if we have two '
) it prints out the filename and the second field (which is the part between the first two '
) delimited by a tab. Then it skipes to the next file.
The result is piped to parallel
. parallel
execute the mv
command by replacing {1}
and {2}
with values given in the columns from the awk
result.
Some notes:
nextfile
is not available in allawk
versions
whitespaces in a filename is never a good idea. You could replace them by an underscore if you change the
awk
command like this:
awk -v FS="'" -v OFS="t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt
- You should move or copy your new filenames to another folder. I'm not sure how
awk
will react if new files appear in the same folder during runtime.
edited 1 hour ago
answered 2 hours ago
finswimmerfinswimmer
4846
4846
add a comment |
add a comment |
for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done
It will search all the files in the current directory and will move this file to the new one.
add a comment |
for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done
It will search all the files in the current directory and will move this file to the new one.
add a comment |
for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done
It will search all the files in the current directory and will move this file to the new one.
for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done
It will search all the files in the current directory and will move this file to the new one.
edited 34 mins ago
answered 1 hour ago
PRYPRY
1,90431024
1,90431024
add a comment |
add a comment |
for src in *.html; do
{ read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
mv -- "$src" "$dst.html"
done
add a comment |
for src in *.html; do
{ read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
mv -- "$src" "$dst.html"
done
add a comment |
for src in *.html; do
{ read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
mv -- "$src" "$dst.html"
done
for src in *.html; do
{ read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
mv -- "$src" "$dst.html"
done
answered 10 mins ago
Stéphane ChazelasStéphane Chazelas
304k57570927
304k57570927
add a comment |
add a comment |
I would do such a thing in perl instead of putting together some slow and fragile tangle of subshells:
perl -e 'while(<>){
sub no_rename { print "rename @_n" }
next unless $. == 3;
if(my ($f) = /DATA POPULATION +'''(.*?)'''/){
$f =~ s/[^w]/_/g;
no_rename $ARGV, $f or warn "rename $ARGV, $f: $!n";
}
close ARGV
}' files ...
You'll have to change no_rename
to rename
to make it actually do it, instead of showing it.
Sorry for the ugly '''
; if you put that in a script file instead of one-liner, that should be simply:
/DATA POPULATION +'(.*?)'/
If you really want to create filenames with spaces, also add a s
after the w
in the s///g
expression (and similar for other characters that could go in the filename -- by default, the script will replace everything but letters and digits with an underscore).
add a comment |
I would do such a thing in perl instead of putting together some slow and fragile tangle of subshells:
perl -e 'while(<>){
sub no_rename { print "rename @_n" }
next unless $. == 3;
if(my ($f) = /DATA POPULATION +'''(.*?)'''/){
$f =~ s/[^w]/_/g;
no_rename $ARGV, $f or warn "rename $ARGV, $f: $!n";
}
close ARGV
}' files ...
You'll have to change no_rename
to rename
to make it actually do it, instead of showing it.
Sorry for the ugly '''
; if you put that in a script file instead of one-liner, that should be simply:
/DATA POPULATION +'(.*?)'/
If you really want to create filenames with spaces, also add a s
after the w
in the s///g
expression (and similar for other characters that could go in the filename -- by default, the script will replace everything but letters and digits with an underscore).
add a comment |
I would do such a thing in perl instead of putting together some slow and fragile tangle of subshells:
perl -e 'while(<>){
sub no_rename { print "rename @_n" }
next unless $. == 3;
if(my ($f) = /DATA POPULATION +'''(.*?)'''/){
$f =~ s/[^w]/_/g;
no_rename $ARGV, $f or warn "rename $ARGV, $f: $!n";
}
close ARGV
}' files ...
You'll have to change no_rename
to rename
to make it actually do it, instead of showing it.
Sorry for the ugly '''
; if you put that in a script file instead of one-liner, that should be simply:
/DATA POPULATION +'(.*?)'/
If you really want to create filenames with spaces, also add a s
after the w
in the s///g
expression (and similar for other characters that could go in the filename -- by default, the script will replace everything but letters and digits with an underscore).
I would do such a thing in perl instead of putting together some slow and fragile tangle of subshells:
perl -e 'while(<>){
sub no_rename { print "rename @_n" }
next unless $. == 3;
if(my ($f) = /DATA POPULATION +'''(.*?)'''/){
$f =~ s/[^w]/_/g;
no_rename $ARGV, $f or warn "rename $ARGV, $f: $!n";
}
close ARGV
}' files ...
You'll have to change no_rename
to rename
to make it actually do it, instead of showing it.
Sorry for the ugly '''
; if you put that in a script file instead of one-liner, that should be simply:
/DATA POPULATION +'(.*?)'/
If you really want to create filenames with spaces, also add a s
after the w
in the s///g
expression (and similar for other characters that could go in the filename -- by default, the script will replace everything but letters and digits with an underscore).
edited 6 mins ago
answered 15 mins ago
pizdelectpizdelect
49716
49716
add a comment |
add a comment |
Daniel Cross is a new contributor. Be nice, and check out our Code of Conduct.
Daniel Cross is a new contributor. Be nice, and check out our Code of Conduct.
Daniel Cross is a new contributor. Be nice, and check out our Code of Conduct.
Daniel Cross is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f498718%2fscript-to-rename-a-large-number-of-files-using-the-text-in-each-file-to-rename%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown