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.
Related
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" {} +
I am trying to run a script named myscript.command on a Mac/Linux machine.
#!/bin/sh
echo 'Starting'
chmod 777 ./myfile
The problem is that when I get to the chmod part I get this output:
chmod ./myfile: No such file or directory
But both myscript.command and the myfile are in the same folder.
EDIT
It seems that when I launch the script the script's location is not being preserved. How can I preserve the location?
The script is being launched via double click in the UI.
$0
In order to change the current working directory to the script's directory, put the following command right after the shebang line:
cd "$(dirname "$0")"
The $0 variable expands to the script name (path to the script), and dirname returns path to the script's directory.
Detecting the current working directory
You can use pwd command to get the current working directory. If you are actually running Bash (I'm not sure, since the shebang in your code points to /bin/sh), you can use the built-in $PWD variable:
PWD
The current working directory as set by the cd builtin.
Storing the script's path into variable
Alternatively, save the directory path into a variable, and use it in the script, e.g.:
dir="$(cd $(dirname "$0"); pwd)"
chmod 770 "$dir/somefile"
Double quotes
Note the use of double quotes. Double quotes prevent reinterpretation of special characters. It is also the way to pass strings containing spaces as a single word:
dir="some directory name"
cd "$dir"
Without double quotes the words are interpreted as separate arguments.
You might start off something like this, too..
#!/bin/sh
echo 'Starting'
if [ -f ./myfile ]; then
chmod 777 ./myfile
else
echo "File does not exist:"
ls -l
fi
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
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/
Hello I need to create folder based on a filename and in this folder create another one and then move file to this second folder
example:
my_file.jpg
create folder my_file
create folder picture
move my_file.jpg to picture
I have this script but it only works on windows and now I'm using Linux
for %%A in (*.jpg) do mkdir "%%~nA/picture" & move "%%A" "%%~nA/picture"
pause
Sorry if I'm not precise but English is not my native language.
#!/usr/bin/env bash
# Enable bash built-in extglob to ease file matching.
shopt -s extglob
# To deal with the case where nothing matches. (courtesy of mklement0)
shopt -s nullglob
# A pattern to match files with specific file extensions.
# Example for matching additional file types.
#match="*+(jpg|.png|.gif)"
match="*+(.jpg)"
# By default use the current working directory.
src="${1:-.}"
dest="${2:-/root/Desktop/My_pictures/}"
# Pass an argument to this script to name the subdirectory
# something other than picture.
subdirectory="${3:-picture}"
# For each file matched
for file in "${src}"/$match
do
# make a directory with the same name without file extension
# and a subdirectory.
targetdir="${dest}/$(basename "${file%.*}")/${subdirectory}"
# Remove echo command after the script outputs fit your use case.
echo mkdir -p "${targetdir}"
# Move the file to the subdirectory.
echo mv "$file" "${targetdir}"
done
Use basename to create the directory name, mkdir to create the folder, and mv the file:
for file in *.jpg; do
folder=$(basename "$file" ".jpg")"/picture"
mkdir -p "$folder" && mv "$file" "$folder"
done
Try the following:
for f in *.jpg; do
mkdir -p "${f%.jpg}/picture"
mv "$f" "${f%.jpg}/picture"
done
${f%.jpg} extracts the part of the filename before the .jpg to create the directory. Then the file is moved there.