Remove specific suffix from all files containing it - batch-rename

Long story short, OneDrive has taken all my files and renamed them to include the string "-DESKTOP-9EI0FN7" at the end of the file name, resulting in files such as:
myTextFile-DESKTOP-9EI0FN7.txt
myVideo-DESKTOP-9EI0FN7.mp4
So I'd like to write a batch script that finds all the files with that string in them, and renames them to remove the string, so:
myTextFile-DESKTOP-9EI0FN7.txt becomes myTextFile.txt
The problem is, I know nothing about writing batch files. Any advice?

Test out with this bad boy:
find . -type f -exec rename -n -e 's/(.*)\-DESKTOP\-9EI0FN7(.*)/$1$2/' {} \;
If the output satisfies you, remove the -n portion and it does actually apply the changes.
Good luck, sir!

Related

Reflection to grab strings from an objective c file

I have a large objective c file filled with hardcoded objects with a description String field on them. They are all constructed like so:
Item *43 = [[Item alloc] initWithFieldId:#"43" description:#"This is test 43 of 100"];
I would like to know if there is a way for me to extract all of these strings in this .m file and write them to a text file. Is there some kind of reflection library that would let me walk this file and grab all the strings starting from description:# ending at the second quotation mark?
Not 100% sure if this is what you're looking for, but you could do it from the terminal pretty easily with a find command and some regex like Bob recommends: (edited to only echo descriptions, not entire file)
find . -type f -name \*.m -exec sed -n 's/Item .*description:#"\(.*\)"].*/\1/p' {} \;
This will return
This is test 43 of 100
for all of the matches.
For the entire line that the search finds use:
find . -type f -name \*.m -exec grep Item\.*description:# {} \;
Since there's a specific pattern to the file you can use Regular Expressions to extract what you need.
There are various editors that internally support regex, but you can always use regex through the Unix command line tools.
Here's a place to start.

add prefix to files with rename - error argument too long

I have thousands of files inside a directory I need to rename adding a prefix like "th_" so that files will be th_65461516846.jpg
but I can't due to the error "argument too long"
I have used this command
rename 's/^/th_/' *
thanks!
The xargs program is used to break command lines into multiple commands to avoid blowing the shell line length limit. In your case, you'd use:
ls | xargs rename 's/^/th_/'
Which repeatedly executes rename with a portion of the output of ls until the list of files is exhausted. Do be aware this idiom requires special attention if the file names have spaces or other funny characters in them (which I'm assuming isn't so based on your example).
This one did the job
for f in *; do mv "$f" "${f/9/th_}";done
or
for f in * ; do mv $f th_${f#} ; done
I don't know what differs between the 2 but in my case they both work.

rename file in bourne shell

I am trying to write a bourne-shell script that takes a directory as a parameter and look for images named ixxx.a and rename them to ixxx_a.img where "xxx means the extension number for exemple image files would be named i001.a , i002.a ,i003.a ...)
here what I tried
mv $1/f[0-9][0-9][0-9].a $1/f[0-9][0-9][0-9]_a.img
but it says that the DEST is not a directory.
Any help would be much appreciated. Thanks.
for i in $1/f[0-9][0-9][0-9].a; do
mv $i ${i%.a}_a.img
done
However, this does not consider blank spaces in the file/folder names. In this case you'd have to use while so you get one file name per line (see below for bonus). There are probably dozens of other ways, including rename.
find $1 -maxdepth 1 -type f -name "f[0-9][0-9][0-9].a"|while read i; do
mv "$i" "${i%.a}_a.img"
done
Edit: Perhaps I should explain what I did there. It's called string substitution and the main use cases are these for a variable var:
# Get first two characters
${var:0:2}
# Remove shortest rear-anchored pattern - this one would give the directory name of a file, for example
${var%/*}
# Remove longest rear-anchored pattern
${var%%/*}
# Remove shortest front-anchored pattern - this in particular removes a leading slash
${var#/}
# Remove longest front-anchored pattern - this would remove all but the base name of a file given its path
# Replace a by b
${var//a/b}
${var##*/}
For more see the man page.

Trying to cat a header into source files but a Unicode BOM is getting in the way

Following the instructions at Add header (copyright) information to existing source files, I need to add copyright headers to a bunch of source files we're sending out of the building. (I know, I hate copyright headers too, but it's policy for when we release proprietary source files. Please consider "persuade someone to waive the policy" as unhelpful and as not answering the question.)
I have two copies of all the files (in dir and dir.orig) and, from within dir.orig, I'm using
find . -name \*.cs -exec sh -c "mv '{}' tmp && cp ../header.txt '../dir/{}'
&& cat tmp >> '../dir/{}' && rm tmp" \;
This is working, but it's ending up with the header, then the BOM from the original source file, whereas I'd prefer either the BOM to move to the start or be removed.
(Looking at this, I realise that moving the file to tmp is unnecessary, given I'm not overwriting the original, but I didn't bother removing that from the example from the other SO question.)
How can I remove (or move) the BOM so that I end up without it appearing immediately after the newly-added header?
I think I may have found my solution, thanks to being pointed to uconv from this answer from Steven R. Loomis on a related question.
If I use
find . -name *.cs -exec sh -c "cp ../header.txt '../dir/{}'
&& uconv --remove-signature -f UTF-8 -t UTF-8 '{}' >> '../dir/{}'" \;
, then uconv assumes both input (-f) and output (-t) encodings should be UTF-8, but --remove-signature causes it to remove any BOM it finds.

Finding files in subdirectories created after a certain date

I'm in the process of writing a bash script (just learning it) which needs to find files in subdirectories created after a certain date. I have a folder /images/ with jpegs in various subfolders - I want to find all jpegs uploaded to that directory (or any subdirectories) after a certain date. I know about the -mtime flag, but my "last import" date is stored in %Y-%m-%d format and it'd be nice to use that if possible?
Also, each file/pathname will then be used to generate a MySQL SELECT query. I know find generally outputs the filenames found, line-by-line. But if find isn't actually the command that I should be using, it'd be nice to have a similar output format I could use to generate the SELECT query (WHERE image.file_name IN (...))
Try below script:
DATE=<<date>>
SEARCH_PATH=/images/
DATE=`echo $DATE|sed 's/-//g'`
DATE=$DATE"0000"
FILE=~/timecheck_${RANDOM}_$(date +"%Y%m%d%H%M")
touch -t $DATE $FILE
find $SEARCH_PATH -newer $FILE 2>/dev/null|awk 'BEGIN{f=0}{if(f==1)printf("\"%s\", ",l);l=$0;f=1}END{printf("\"%s\"",l)}'
rm -f $FILE
You can convert your date into the "last X days" format that find -mtime expects.
find is the correct command for this task. Send its output somewhere, then parse the file into the query.
Beware of SQL injection attacks if the files were uploaded by users. Beware of special-character quoting even if they weren't.