linux bash script to create folder and move files - linux

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.

Related

Copy a file from a directory and paste it to multiple sub directories in linux(ubuntu) terminal?

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

Having trouble implementing cp -u in 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

I have series of file in OLD dir, I want to check if the file exist in NEW dir. If it does not exist, I would like to do few operations on it

For instance... I have some files in the format mmddyy.zip in the OLD directory...
041414.zip
041514.zip
041614.zip
041714.zip
041814.zip(today's file Apr 18 2014)
and I have a NEW dir with 041414.zip 041514.zip in it...
I'm trying to copy all the files from OLD to NEW and do some other operations if that file doesn't exist in NEW dir...
I'm thinking of doing it ' while do' statement, but not sure what what to use in the condition...
Thanks,
Sam.
You probably want to use find, and execute a script that does both the check and the operation.
For instance, script.sh (fill in your own variables):
#!/bin/sh
FNAME="`basename $1`"
NEWDIR="/tmp"
NEWFNAME="$NEWDIR/$FNAME"
if [ ! -f "$NEWFNAME" ]; then
# do stuff to "$1"
# optionally cp "$1" "$NEWFNAME"
fi
Then you run something like cd /old/dir; find -name "*.blah" -exec script.sh "{}" ";"

How to copy a file to a folder if there is already a file with the same name (Linux BASH)

For example, if I create a dustbin folder and it has ~/dustbin/File01 already in it, how would I copy a new file into the folder with the same name?
E.g.:
cp ~/test/File01 ~/dustbin/File01
But add perhaps (Copy) to the end of it
Unix filesystems don't allow two files with the same name in the same folder (for reference, VMS did allow that).
You can use cat with append:
cat ~/test/File01 >> ~/dustbin/File01
This creates the file when it doesn't exist or appends to an existing file.
Also the cp command offers options to make backups so it doesn't overwrite existing files. See the --backup option for that.
I think you're asking how to detect if a file already exists and then rename the new file so it doesn't overwrite. In that case:
if [[ -f "$HOME/dustbin/File01" ]]; then
cp "$HOME/test/File01" "$HOME/dustbin/File01 (Copy)"
else
cp "$HOME/test/File01" "$HOME/dustbin/File01"
fi
is literally what you asked for. You can do this more generally:
if [[ -f "$dest" ]]; then
cp "$source" "${dest%/*}/${dest##*/} (Copy)"
else
cp "$source" "$dest"
fi
But you run the risk of having "(Copy) (Copy) (Copy) (Copy) …" in your filename if you use it carelessly.
dd if=~/test/File01 >> ~/dustbin/File01

Linux, how to create file using directory name?

How to create folders like: wdw/1/11, wdw/2/22, ... wdw/6/66, ..., wdw/9/99, and file using directory name in the deepest directory like directoryname_file.txt
In bash:
mkdir wdw # Creates the top dir.
mkdir {1..9} # Creates the subdirs using brace expansion.
for dir in {1..9} ; do
mkdir $dir/$dir$dir # Creates the subsubdirs.
touch $dir/$dir$dir/$dirdir"_file".txt # Creates the file.
done
In Bash, you can use the mkdir command:
your_dir="wdw/1/11"
if [ ! -d $your_dir ]; then
mkdir $your_dir
fi
The IF clause is to check if the directory already exists.
You can loop to change the value of "your_dir" with /2/22, 6/66, etc...
You'll have use the -p flag with mkdir to create nested directories, for example:
dir_name="wdw/1/11"
mkdir -p $dir_name
Then use touch or echo to create the files:
touch $dir_name/directoryname_file.txt
or
echo "some text" > $dir_name/directoryname_file.txt

Resources