A slightly complicated Linux scripting question, could I humbly ask for help ? :)
Hello there !
Non-hentai stuff, I’d like to have help with Linux commands. If that’s your field of expertise, thanks if you can lurk around one more minute, and read the rest of this post ^^
There’s a little something I’d like to be able to do in batch, in order to save time.
However, look, I’ll be frank, I have no idea how to do it.
I don’t doubt that’s doable (the amazing wonders one can achieve with a bash script, or even with a single command taking just one line have left me speechless countless times)… but I have no idea how to do it ^^
So, if you think you are able to write a bash script for this, or at least a simpler way, I would be MOST grateful
***
The context :
– I keep a copy of the zips of my shares stored in a non-public location, and, to upload them to file hosts, rather than uploading them from my computer, I tell the file hosts : “look, take the file from here, I’m giving you the exact URL”. That’s called “remote upload”, and it divides by 3 or 4 the time required to publish stuff online. It also makes it easier to create big packs of zips. And I have a safe place to keep my stuff even if my hard disks all (yeah : “all”; I’m paranoid, no important info isn’t stored twice) die at the same time at home
– Occasionally, one or several of my files are deleted from file hosts. And it happens that some file hosts sometimes also blacklist the exact name of the deleted file, or blacklist the file’s MD5 hash.
I’m not sure my current file hosts do that, but it’s a possibility.
– Against such occurences, I have a trick, I rename the zips with something like adding an underscore in the end, and I update the zips with a different copy of one of the files I place in all my zips. –> Different name, different hash sum.
This zip updating thing is quite simple, I use the file “notes and info from the uploader.txt“, present in all my shares.
I have uploaded a copy of this text file to the directory where my zips are stored.
I launch the text editor nano to change this “notes and info from the uploader.txt” file, I add a space somewhere, replace a punctuation symbol, anything. That’s now a different file.
And then I run “zip -fv” for the file of my choice : it will only freshen what it finds, and replace it if it’s different : that only matches the file “notes and info from the uploader.txt”
And, there, I can once again remote upload that file, it will appear entirely different to the file hosts, without any risk of being blocked.
***
An example, the file
Karomix,_Karorful_Mix_EX11_(www.hentairules.net)_(English).zip
I’ll rename it to
Karomix,_Karorful_Mix_EX11_(www.hentairules.net)__(English).zip
with
mv Karomix,_Karorful_Mix_EX11_(www.hentairules.net)_(English).zip Karomix,_Karorful_Mix_EX11_(www.hentairules.net)__(English).zip
And I’ll run
either
zip -fv Karomix\,_Karorful_Mix_EX11_\(www.hentairules.net\)__\(English\).zip
or
zip -fv “Karomix,_Karorful_Mix_EX11_(www.hentairules.net)__(English).zip”
There, done.
***
However, you’ll agree, it’s a bit time-consuming if I want to do that to a dozen files.
To make it faster, I can prepare my operations in my Windows text editor Notepad++, with quick copy-and-paste and stuff.
But, even then, it takes time.
***
I wonder… Do you think it would be possible to script it on my Debian server ?
A bash script that would simply wait for me to input the name of a file, and that would add the final underscore (for instance with a variation on [ rename ‘s/\_(English$/\__(English/’ filename ] , although I have no idea how to exactly write it or if the apostrophe doesn’t need to be escaped) and run a zip -fv on it.
Maybe something even simpler, a [find . -name ‘filename’ -exec rename_with_all_the_options_lol_ zip -fv {} \; ], who knows ^^
Or even more awesome, a script that would parse a file with a list of filenames (I would have added those filenames myself before this) and would run this command on each of the file names.
***
In your opinion, is this pure sci-fi, or could that be actually done ?
This time gain would mean bliss and more time to “live” for me…
I’d even welcome a Coding Angel From Coding Heaven who would provide me the script
Well, thanks if you’ve got your idea on this that you could share
Thank Zeus for StackOverflow.com, when the guys there aren't being assholes, they can be useful:
http://stackoverflow.com/questions/15290186/find-…
And substitute rename where he uses mv, etc, etc.
Also I found this:
http://www.tecmint.com/35-practical-examples-of-l…
I think the find command has some options that find a list of files with stated parameters and dump them into a text file
FINAL EDIT: Okay, I love a good programming challenge, but here's what I think you're asking for.
1. Your search-and-edit script in pseudocode
write("Enter filename.");
string filename = read(user_input);
find filename <with all of find's flags> 'rename <with all of rename flags> filename_.zip'
2. Your input.txt multifile script in pseudocode
read(input.txt)
while (!EOF)
{
string filename = readline(input.txt);
find filename <with all of find's flags> 'rename <with all of rename flags> filename_.zip'
}
Something along those lines correct?
Thanks man ^^
Yeah, this is something along these lines.
Thinking back, I'm not a fan of the program asking me the file names one after the other, because that would have me hanging in front of my terminal (Putty Connection manager) for a prolungated time. I'm more in favour of the option where I manually populate a text file with zips names and then run the bash script.
I went with the way suggested by Ion, as it was the only one that was immediately usable and testable.
You can see it a few comments below… you are welcome to partitipate in there, thank you ! ^_^
I'm not ire if someone has already provided a script. But if they haven't Ill write one up tomorrow for you…
Its really quite simple, just would prefer to test it onmy Linux box first..
The gist of it is this:
#!/bin/bash
for f in`ls`;do
mv $f ${f}_
done
make sure you chmod 755 the file ofcourse.
If you are interested I'll write it up and test it out tomorrow first..
Hey Foolord, thank you ^^
I went with the script provided by Ion, cf one comment below, as that one was almost usable (although flawed somewhere, for the moment ). You're welcome to also take a look
Regarding the code you suggested, may I ask what it is doing, actually, as you wrote it ?
With my limited knowledge (I once read a pro linuxian complain that I was openly confessing my ignorance, but, lol, it's better like that !), I don't really see what it does.
First, where is f defined ?
Second, wouldn't you add an underscore after the final .zip string ?
#!/bin/sh
echo ” ” >> upload.txt
for file in *.zip
do
mv $file ${file%_\(English\).zip}__\(English\).zip
zip -fv ${file%_\(English\).zip}__\(English\).zip
done
Tried to use that, thank you
Clean version of what I ran, just in case : http://pastebin.com/ZmWC3ZNB
However, it didn't entirely work, although I created the proper text file with only the two filenames I wanted to process, the script went on and decided to process EVERY ZIP FILE in the current directory. I had to control-Z its face and restore the zips that lost their names as they were being rezipped *_*
Would you know why, maybe ?
My bad. I think I misunderstood some things (was late at night for me). I think you're correct about modifying the file to change the MD5. Just adding a space is easiest, that's what the first line is. Which should read
echo " " >> "notes and info from the uploader.txt"
In the script replace *.zip with $@. This means that it will only proocess files given to the script as arguments. Assuming you called it "fix-shit.sh" you can then call it using:
./fix-shit.sh file1.zip file2.zip file3.zip
You can optionally use a text file as you wanted to do before using:
cat input.txt | xargs ./fix-shit.sh
And by processing every file : I mean it, it would have taken a full day and processed all files. It started in the alphabetic order, and went on, and on, and on.
Next time I'll do tests in a test folder in which I only copied a dozen zips, asking to process two or three of them ^^
Still, yeah, something's off… Thanks a lot for help with fixing it !
the line
for file in *.zip
tells the script to process every .zip file it finds. You can replace the "*.zip" part with filenames
Ex:
for file in "file 1.zip" "file_2.zip" "file3.zip"
SD121 is correct. The * is the multiple character wildcard. You can use ? as a single character wildcard or put a character before or after the * to filter certain filenames.
For example d*.zip only looks for zip files that start with d.
Yeah, but the idea is to process all files (or all zips, it's the same) listed in the aforementioned text file. While, here, it went on to process all zip files present in the same directory as the script. That's a hell of a difference…
For the editing of the notes and info from the uploader.txt. If you have a copy of the file in the same folder of your zip files, you can add a special string in it, that your script changes every time you run it. To make it really simple, I wold add the utc time to the last line of the file, just as a token, then using sed, you can cut this last line of the file, and have the script re-calculate the utc time and added at the end of the file, thus every time you run your script, a new utc string will be replace the old one.
I've done it like this
#!/bin/bash
#I delete the last line of the txt file
sed -ie '$d' notes and info from the uploader.txt
#calculete the utc time now and added to the txt
date +%s >> notes and info from the uploader.txt
Hope it helps
oops, I forgot to remove the e in sed -ie, so that sed doesn't create a backup of your file with extension e, just sed -i notes and info from the uploader.txt.
Ah, I didn't think of automatically updating the notes and info from the uploader.txt file !
That's a good idea, this way, I don't need to periodically update it ! Huge props ! O_O
For the editing of the notes and info from the uploader.txt. If you have a copy of the file in the same folder of your zip files, you can add a special string in it, that your script changes every time you run it. To make it really simple, I wold add the utc time to the last line of the file, just as a token, then using sed, you can cut this last line of the file, and have the script re-calculate the utc time and added at the end of the file, thus every time you run your script, a new utc string will be replace the old one.
Here's my solution. It doubles a random underscore in the filename each time it is run and rezips it.
As written it works on one file at a time by taking the filename from the first argument "scriptfilename <name of file>"
shouldn't be difficult to change it to run through a list of filenames automatically either, let me know if you're interested.
#!/bin/bash
#sets the file name taken from the first argument
file="$1"
#counts the number of underscores so we can choose a random one to double
position=`echo "file" | grep -o "_" | wc -l`
#chooses a random number from the count of underscores
n=`shuf -i 1-$position -n1`
#sets the new file name
#doubles a random underscore
new_file="`echo "$file" | sed "s/_/__/$n"`"
#moves old file to new file
mv "$file" "$new_file"
#zips new file
zip -fv "$new_file"
Thanks for the input, SD121 !
To be frank, I'm not a huge fan of the randomness of the process, I fear that, over time, file names may become grotesque. While here, if the underscores remain in the end, that still keeps a "unified" pattern until the very end of the file name.
That, these are aesthetical reasons.
Also, that would randomize the alphabetical order in which the files are listed.
And, that, this is very bad lol
So, no, not that ^^ Still, thank you
I've gone with the script proposed by Ion, a few comments above, however we haven't quite yet sorted that issue, you're welcome to take a look if you have more time ^^
Okay, so did you find a final solution (err…maybe I'll use a different phrase), a fix for your issue? Sorry, I could not be of more help.
well if I might help on the randomness.
for each file generate a random number
then do a simple substitution swap for each digit. eg 1=a,2=b…etc so 1432 =adcb.
then take string and put it in brackets at the end of the filename somefilename_(english)-[adcb].zip
also just put the string in a file checksum.txt you include in the zip as a way to randomize the zip file again.
that way you don't have to change the notes file, and the 'random' string is easy to remove and replace with a new one.
for that you could use (assuming it's named in the format blah_blah_(english)-[#####].zip)
mv $file ${file%_(english)-*}_(english)-[$RANDOM].zip
Here's a quick bash script to change the name and shasum of a .zip file
As a bonus, it doesn't require opening the zip at all. it does a cheap trick and pastes a uuid into the comment to shuffle the hash instead. I'm too lazy to stick it in a loop or make it accept collections, but that's the easy part.
#!/bin/bash
echo -e "sha + filename:n`shasum $1`"
zip $1 -z -q <<EOF
`uuidgen`
'.'
EOF
f="${1/.zip}"_.zip
mv $1 $f
echo -e "new sha + filename:n`shasum $f`"