I'm looking for a Linux command to move files from a directory to another, but only if their file name doesn't end with .zip.
Is their a command like: mv ~/Folder1/!*.zip ~/Folder2/?
Try this:
mv $(ls ~/Folder1/ |grep -v "zip$" ) ~/Folder2/
If your shell is bash and the option extglob is enabled, you can do it like this too
mv ~/Folder1/!(*.zip) ~/Folder2/
Try this command:
mv ~/Folder1/!(*.zip) ~/Folder2/
Related
I have a directory mnt/d/LIVI.
Inside the directory, LIVI, I have sub-directories:
mnt/d/LIVI/ak
mnt/d/LIVI/ag
mnt/d/LIVI/few
mnt/d/LIVI/ww4
mnt/d/LIVI/ks5
I wanted to copy a file named tt.txt from mnt/d/LIVI/ak/tt.txt and paste to all the sub directories of LIVI, using Ubuntu terminal. How do i do it using a shell script file?
I tried the following one, but it didn't work.
I created a text file named mnt/d/LIVI/FOLDERS.txt, This listed all the sub directories names.
And saved a script file in mnt/d/LIVI directory. The following is the script
#!/bin/sh
# -*- coding: utf-8-unix -*-
ROOTDIR=$(dirname $0 | xargs readlink -f)
for SIMDIR in cat FOLDERS.txt | xargs readlink -f ; do
cp mnt/d/LIVI/ak/tt.txt $SIMDIR
done
#cd ..
date
You may try this bash script
#!/bin/bash
cd "${0%/*}" || exit
for dir in */; do
if [[ $dir != 'ak/' ]]; then
cp ak/tt.txt "$dir"
fi
done
The script must reside under the diectory mnt/d/LIVI
Don't read lines with for.
(If you really wanted to, the syntax for that would look like
for dir in $(cat FOLDERS.txt); do
...
but really, don't. The link above explains why in more detail.)
I don't see why you want to run readlink on the directories at all?
cd "$(dirname "$0")"
while read -r dir; do
cp ak/tt.txt "$dir"
done <FOLDERS.txt
Note also Correct Bash and shell script variable capitalization
I have to make a script which will copy all files from a certain location starting with "db." to another location. My script works fine for all files which are directly in the directory, but it doesnt copy any files which are in subdirectorys. I have used the parameter -r, which should copy everything recursivly or not? Why isnt it working and how can I make it work?
My script:
#! /bin/bash
#Script zum kopieren aller Dateien welche mit "db." beginnen.
#User input
echo -n 'Enter path to copy from: '
read copypath
echo -n 'Enter path to save to: '
read savepath
cp -r $copypath/db.* $savepath
echo 'Done.
Making an answer out of my comment...
try $copypath/db.* followed by $copypath/**/db.*
The first one is for the top level directory (copypath) and the next for any of the subdirectories.
-r does not work here because you don't supply any source directories to cp.
Before cp is executed bash expands the * and gives the resulting file list to cp. cp then only sees something like cp -r 1stFile 2ndFile 3rdFile ... targetDirectory -- therefore -r has no effect.
As pointed out in the comments, you have to use bash's globstar feature ** or find. Also, you should make a habit of quoting your variables.
# requires bash 4.0 or higher (from the year 2009, but OS X has a really outdated version)
shopt -s globstar
cp "$copypath"/**/db.* "$savepath"
or
find "$copypath" -type f -name 'db.*' -exec cp -t "$savepath" {} +
Im trying to move all the contents of the current directory to a new folder in the current directory using a script
mv !\(.svn\|$line\|.\|..\) $line
error is
mv: cannot stat '!(.svn|RSSIFXServicesCommon|.|..)': No such file or directory
I echoed the command to output and if i copy and execute the command myself, it works.
I tried enabling extglob
With extended regex (shopt -s extglob), there's no need to quote your regex:
mkdir -p /tmp/t/4
touch /tmp/t/{1,2,3}
shopt -s extglob
cd /tmp/t
mv !(4|.|..) 4
This also works if I put this in a shell script.
For a school project, I have a shell script that is supposed to copy the files in two directories (without looking at subdirectories) into a third directory. I'm testing out the -u command so that if two files have the same name, only the newer one will get copied over (that's also a spec). My shell script looks like this (excluding #! and error checking):
cd $1 #first directory
for file in `ls`; do
if [ -f $file ]; then
cp "$file" ../$3 # $3 is the third directory
fi
done
cd ../$2
for file in `ls`; do
if [ -f $file ]; then
cp -u "$file" ../$3
fi
done
My current shell script will copy files that don't exist in directory 3 already, and it won't overwrite a newer file with an older file with the same name. However, my shell script doesn't overwrite an older file with a newer file of the same name in directory 3. I don't think there's anything wrong with the -u command. Can you help find the bug in my code? Thanks!
You are missing the -u option in the first loop:
cp "$file" ../$3 # $3 is the third directory
should instead read:
cp-u"$file" ../$3 # $3 is the third directory
If I have a shell script where I get the parent folder using "../" can I expand that out somehow into it's absolute path?
You want readlink -f.
$ cd /tmp
$ readlink -f ..
/
Use realpath
$ realpath ..
/home
While you can often get the full path of a directory using stat, you can also use pwd -P ... however, it isn't much help unless you actually cd to the directory you are interested in.
To get around this limitation without actually changing the current working directory, I've found it fine to just run that cd in a sub-shell, as in:
THIS=`dirname $0` # Which is often "."
PARENT=$(
cd $THIS # At this point, we are sure we're in script's directory
dirname `pwd -P`
)
echo "PARENT=$PARENT"
When using in cmd line:
dirname $(pwd)
When using in shell script:
PROJ_DIR=$(dirname $(pwd))