Rename multiple files with zmv but not directories - linux

I would like to rename multiple files (add an extension).. i can use zmv of zsh with
autoload zmv
zmv -n '(**/)(*)' '$1$2.myextension'
but this will rename also all the dirs that are inside the current dir... what can i do to rename only files (recursively) and avoid dirs renaming?

From here:
# Rename names of all files under the current Dir to lower case, but keep Dir names as-is.
$ zmv -Qv '(**/)(*)(.D)' '$1${(L)2}'
so I think the (.D) is what you require. The 'period' indicates matching on regular files (not directories) and the D enables the GLOB_DOTS option.

Related

How to rename all the files from a directory?

So, i have a given directory, and that directory contains other subdirectories, and every subdirectory can contain a file. I have to change all the files names, so that it will end in ".txt" .
**You can do something like this using bash : and go over all your directories with it **
for f in *.their_current_end;
do
mv -- "$f" "${f%.their_current_end}.txt"
done
another solution would be using : rename in Linux
rename [OPTIONS] perlexpr files
where the rename will rename all the files mentioned like the regex supplied in the perlexpr parameter.
example :
rename 's/.html/.php/' \*.html

Rsync, include only certain files types excluding some directories

I want to rsync only certain file types (e.g. .py) and I want to exclude some directories (e.g. venv).
This is what I have tried:
rsync -avz --include='*/' --exclude='venv/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/
But it doesn't work.
What am I missing?
With rsync you do not need to use --include="*.py" to include '*.py' files in the copy. The --include option will only include files that have been excluded by --exclude= before. rsync specifies ** as the wildcard specifier. For example, if you want to copy all .py files in the current directory (and subdirectories), but not copy anything from the venc directory, you can do something similar to:
rsync -uav --exclude="venc" **.py destination
(note -a implies -rlptgoD)
which would recursively copy all .py files in present working directory to destination excluding the venc directory.
To recursively copy only *.py files from all directories below the current path excluding any venc directories, you can build a temporary file with the results of find containing the *.py files and exclude files containing venc/ as part of the path, and then transfer all filenames in the temporary file using the --files-from and --no-R (no relative) options to rsync as:
$ find /path/to -type f -name "*.py" | grep -v 'venc/' > tmpfile \
rsync -uav --no-R --files-from=tmpfile / host:/dest/dir \
rm tmpfile
This will capture all *.py files in any subdirectories excluding all directories including the name venc/ and anything below them. The --no-R option is needed to prevent the absolute filenames in tmpfile from be taken as relative to the current working directory.

Zip folder exclude some folders

I'm trying to backup my www-folder but hidden folders like .config inside www are added to the backup. I want to exclude the folder "backups" and all folders (and files) starting with a dot.
The problem is that it copies all the hidden folders like .config to the zip-file.
Current code:
zip -r /var/www/backups/site/$(date +\%Y-\%m-\%d-\%H-\%M).zip /var/www -x "*backups*" "*.*" "*/.*"
This should work for you.
zip -r --exclude=*backups* --exclude=*/.* /var/www/backups/site/$(date +\%Y-\%m-\%d-\%H-\%M).zip /var/www
Use a linux find command with an exclude flag, then pipe it into zip.
The following command will exclude all paths under the current directory containing the keywords "backups" or files with "/." in the path and then pipe the files into zip.
find . | grep -v "\(backups\|/\.\)" | xargs zip archive.zip

Zipping everything in directory with 7z except one file or one file type

i'd like to zip everything except one file
7z a -tzip files.zip *
this will zip all the files in my current directory.. is there a way I can tell it to not zip one file or one file type ?
Per the 7za command-line help, you use the -x switch to do this:
-x[r[-|0]]]{#listfile|!wildcard}: eXclude filenames
To exclude the file foo.txt you would add:
-x!foo.txt
To exclude all .html files (*.html) you would add:
-x!*.html
You can add multiple -x entries to exclude multiple filenames and/or wildcards in one zip command. Adding the following will exclude foo.txt and *.html:
-x!foo.txt -x!*.html
So with your example, this would add all files to files.zip EXCEPT files named "FILENAME" or that matched the *.extension wildcard:
7z a -tzip files.zip * -x!FILENAME -x!*.extension
If you are using batch script do not forget to escape ! mark.
7z a -xr^^!*.xml "dest_dir.zip" "Source_dir"

Match all files under all nested directories with shell globbing

Is there a way to use shell globbing to identify nested directories?
so if I have dir/dir1/dir2/dir3/dir4/dir5/.. and I have files under all of them, what is the equivalent globbing pattern to match all files under all directories, similar to - for example - ls -R
In Bash 4, with shopt -s globstar, and zsh you can use **/* which will include everything except hidden files. You can do shopt -s dotglob in Bash 4 or setopt dotglob in zsh to cause hidden files to be included.
In ksh, set -o globstar enables it. I don't think there's a way to include dot files implicitly, but I think **/{.[^.],}* works.
Specifically about git (gitignore, gitattributes, and commands that take filenames): if the pattern contains no slash, * wildcards will match deep. If it does contain a slash, git will call fnmatch with the FNM_PATHNAME flag, and simple wildcards won't match slashes. ** to match deep isn't supported. Maybe this kind of deep matching could be more widely supported with a new FNM_STARSTAR flag, and an implementation in glibc, gnulib and other places.
If you want to act on all the files returned by find, rather than just list them, you can pipe them to xargs:
find <directory> -type f | xargs ls
But this is only for commands that don't have a recursive flag.
You may try:
**/*.*
However it'll ignore hidden files (such as .git files). Sometimes it's a life-saver.
Read more at: What expands to all files in current directory recursively? at SO
You can use tree, it will show all folders recursively.
tree <path>
There is no way to do this with vanilla Bash, however most commands accept a -R or --recursive option to tell them to descend into directories.
If you simply want to list all files located anywhere within a directory or its sub-directories, you can use find.
To recursively find files (-type f) with a given directory:
find <directory> -type f

Resources