what's the meaing of the '~' in makefile? - makefile

I just started to learn how to write makefile.Then I followed the tutorial on the website.I can't understand the meaning of '~' of the last line of the Makefile5 in this tutorial.I have read the explain of GNU make for this wildcard, but it seems that these cases don't match the usage of the below.
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~

Tilde at the end of files simply means they are some kind of backups created by text editors.
You can find a little discussion about this type of files here: What does the tilde at the end of a file name stand for?

rm -f *~ just removes file with names ending with a tilde (~)

Related

How to remove suffix from file in Bash?

I found out that you can apparently add suffix on the fly, this is useful for me to disable a service that relies on the existence of file extension.
$ mv -v file.txt{,.bak}
renamed 'file.txt' -> 'file.txt.bak'
But how can one do the reverse ? What command I have to use ?
$ mv -v file.txt.bak{??}
renamed 'file.txt.bak' -> 'file.txt'
Your command (mv -v file.txt{,.bak}) relies on Bash brace expansion, which translates file.txt{,.bak} to file.txt file.txt.bak. Check out the Bash manpage section for "Brace Expansion". In this case ({,.bak}), there are two strings in the comma-separated list: an empty string and .bak. As such, you can add extensions and the like.
Several examples come to mind for removing extensions using brace expansions (all expanding to mv -iv file.txt.bak file.txt):
mv -iv file.txt{.bak,}
f=file.txt.bak; mv -iv ${f%.bak}{.bak,}, which doesn't presuppose the filename preceding the ".bak" extension (in the Bash manpage, see "Remove matching suffix pattern")
f=file.txt.bak; mv -iv ${f%.*}{.${f##*.},}, which doesn't presuppose any specific extension (in the Bash manpage, additionally see "Remove matching prefix pattern")
As an alternative, and as another contributor suggests, rename is a useful and powerful utility (e.g., rename 's/\.bak$//' *.bak).
P.S. Whenever documenting or scripting variabilized examples, I generally recommend quoting for whitespace safety (e.g., mv -iv "${f%.*}"{."${f##*.}",}).
why donot use rename command.
rename '.bak' '' fileNames
You can use:
file.txt{.bak,}
In this way you substitute the word before the comma with the empty string that is after the comma.

move command with regular expressions

Bash is not recognizing the regular expression in this mv command:
mv ../downloads'^[exam].*$[.pdf] ../physics2400/exams
I'm trying to move files from a download directory to what ever directory I have made for them to go into.
An example of such a file is 'Exam 2 Practice Homework (Solutions).pdf'
(the single quotes are part of the file in Bash apparently.
There are many other files in the download folder hence the regex or the attempt anyway.
When performing filename expansion, Bash does not use regular expressions. Instead, a type of pattern matching referred to as globbing is used. This is discussed in the Filename Expansion section of the Bash manual.
In regards to your example file name (Exam 2 Practice Homework (Solutions).pdf), here are a couple things to note:
the single quotes are not part of the file name, but are a convenience to avoid having to escape special characters in the filename (i.e. the spaces and the parentheses). Without the quotes, the filename would be specified Exam\ 2\ Practice\ Homework\ \(Solutions\).pdf. See the Quoting section of the Bash manual for further details.
filesystems in Unix-like operating systems are case sensitive, so you need to account for the upper case E the filename starts with
Here's a pattern matching expression that would match your example filename as well as other files that start with Exam and end with .pdf.
mv ../downloads/Exam*.pdf ../phyiscs2400/exams
If you have files that start with both Exam and exam, you could account for both with the following:
mv ../downloads/[Ee]xam*.pdf ../phyiscs2400/exams
The bracketed expression is interpreted as "matches any one of the enclosed characters". This allows you to account for both upper and lower case.
Before executing such mv commands, I would test the filename expansion by running ls to verify that the intended files are matched:
ls ../downloads/[Ee]xam*.pdf
If you want to use the regular expression, how about this?
find ./downloads -regex '.*\.pdf' -exec mv '{}' exams/ \;

How can I delete a file whose name starts with "#"?

There is a file #A.py# that appears to be a copy of the original A.py in the same directory - when I try rm, I get the following:
rm: missing operand
What does the ## notation mean? How did this file appear?
Add quotes around:
rm "#A.py#"
Without quotes it's interpreted as a beginning of the comment
You could also escape the #:
$ touch \#rmme
$ ls|grep \#
#rmme
$ rm \#rmme
Like mention in other answers by using quotes should work:
rm "#A.py#"
Also this:
rm \#A.py\#
To remove all:
rm \#*
And just in case check the option --
The rm command supports the -- (two consecutive dashes) parameter as a delimiter that indicates the end of the options. This is useful when the name of a file or directory begins with a dash or hyphen. For example, the following removes a directory named -dir1
rm -- -filename

Mass renaming of files in folder

I need to renami all the files below few files format in the folder in such a way that last _2.txt will be the same and apac, emea, mds will be the same in all files but before _XXX_2.txt need to add logs_date to all the files.
ABC_xyz_123_apac_2.txt
POR5_emea_2.txt
qw_1_0_122_mds_2.txt
to
logs_date_apac_2.txt
logs_date_emea_2.txt
logs_date_mds_2.txt
I'm not sure but maybe this is what you want:
#!/bin/bash
for file in *_2.txt;do
# remove echo to rename the files once you check it does what you expect
echo mv -v "$file" "$(sed 's/.*\(_.*_2\.txt\)$/logs_date\1/' <<<"$file")"
done
Do you have to use bash?
Bulk Rename Utility is an awesome tool that can easily rename multiple files in an intuitive way.
http://www.bulkrenameutility.co.uk/Main_Intro.php
Using mmv command should be easy.
mmv '*_*_2.txt' 'logs_date_#2_2.txt' *.txt
You could also use the rename tool:
rename 's/.+(_[a-z]+_[0-9].)/logs_date$1/' files
This will give you the desired output.
If you don't want to or can't use sed, you can also try this, which might even run faster. No matter what solution you use, be sure to backup before if possible.
shopt +s extglob # turn on the extglob shell option, which enables several extended pattern matching operators
set +H # turn off ! style history substitution
for file in *_2.txt;do
# remove echo to rename the files once you check it does what you expect
echo mv -v "$file" "${file/?(*_)!(*apac*|*emea*|*mds*)_/logs_date_}"
done
${parameter/pattern/string} performs pattern substitution. First optionally a number of characters ending with an underscore are matched, then a following number of characters not containing apac, emea or mds and ending with an underscore are matched, then the match is replaced with "logs_date_".
Copied from the bash man page:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
#(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns

Bash Wildcard use

I am trying to remove files in a directory using rm and without deleting the directory itself in a script. The examples I see only do this while in the directory itself, and I would like to do it without navigating there.
I tried
rm "$(dirname $1)/filetokeep/*"
but it is not working. Any help?
Quoting the wildcard inhibits expansion.
rm -- "$(dirname -- "$1")/filetokeep"/*
Using -- ensures that values can't be interpreted as optional arguments rather than positional ones (so that things still work if the directory named in $1 starts with a -).

Resources