A slightly complicated Linux scripting question, could I humbly ask for help ? :)

1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 4.00 out of 5)
Loading...
By Oliver (AKA the Admin) on 21 comments
in Categories: Just Talking

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 :twisted:

– 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 :)

Subscribe
Notify of
guest

21 Comments
oldest
newest most voted
Inline Feedbacks
View all comments
oldbrokenhands
oldbrokenhands
9 years ago

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?

Oliver AKA The Admin
Admin
9 years ago
Reply to  oldbrokenhands

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 ! ^_^

FooLord
FooLord
9 years ago

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..

Oliver AKA The Admin
Admin
9 years ago
Reply to  FooLord

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 :D ). 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 ?

Ion
Ion
9 years ago

#!/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

Oliver AKA The Admin
Admin
9 years ago
Reply to  Ion

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 ?

Ion
Ion
9 years ago

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

Oliver AKA The Admin
Admin
9 years ago
Reply to  Ion

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 ! :)

SD121
SD121
9 years ago

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"

oldbrokenhands
oldbrokenhands
9 years ago

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.

Oliver AKA The Admin
Admin
9 years ago
Reply to  oldbrokenhands

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…

scriptReply
scriptReply
9 years ago

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

scriptReply
scriptReply
9 years ago
Reply to  scriptReply

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.

Oliver AKA The Admin
Admin
9 years ago
Reply to  scriptReply

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

scriptReply
scriptReply
9 years ago

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.

SD121
SD121
9 years ago

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"

Oliver AKA The Admin
Admin
9 years ago
Reply to  SD121

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 :D

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 ^^

oldbrokenhands
oldbrokenhands
9 years ago

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.

wyld_one
wyld_one
9 years ago

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.

Ion
Ion
9 years ago

for that you could use (assuming it's named in the format blah_blah_(english)-[#####].zip)

mv $file ${file%_(english)-*}_(english)-[$RANDOM].zip

guy
guy
9 years ago

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`"