create multiple folders using existing file names in linux - bash

i have downloaded several pdf files(with various names) and stored them in a specific directory (for example, Downloads/directory1).
i would like to create folders to store these files under the same directory, using the names of the original files, but without the extension pdf.
for example, for a file named maths.pdf, i want to create the folder maths and store the pdf in it.
i made several attempts creating a script using commands as basename and for, but i didn't have any luck.

You can do:
Assuming you're getting:
filename='Downloads/directory1/math.pdf'
f="${filename##*/}"
dir="${f%.*}"
mkdir -p "$dir"
will create mathdirectory

try with:
cd Downloads/directory1
for f in *.pdf; do
fname=${echo $f | sed "s/.pdf//" }
echo "Creating directory [$fname]"
mkdir "$fname"
done

Related

Copy files to their corresponding destination folders

I have many files in a folder with different extensions (.txt, .ascii, .mat). I want to move them to the destination folder which would be same as file names.
For example:
I have files like a.txt, a.ascii, b.txt, b.ascii, b.mat.
I want to make folder first in the name of a and b, then I want to move files a.txt,a.ascii to folder a and b.txt,b.ascii,b.mat to folder b.
I tried the code as follows. However I need an automatic way to make folder and move the files to it.
#!/bin/sh
mkdir a b
for file in $(<list.txt)
do
cp "$file" a
done
Seems that this Bash script can do the job
#!/usr/bin/env bash
for file in $(<list.txt); do
dirn="${file%.*}"
mkdir -p "$dirn"
cp "$file" "$dirn"
done

Failed to copy list of files to another folder

I have a text file called "list.txt" that contain all the directories of the files that need to be copied to a new folder (dir_newfolder). I wrote the code like below:
for file in $(cat list.txt); do cp ${file} dir_newfolder; done
I got list of errors: cp:"file_name":No such file or directory. The file_names are the lines pulled out from the "list.txt". But when I copy each file_names from the error message and use cp to copy to the new folder. There is no error.
I am using mac os terminal.
Thanks in advance.
Copy a file or folder locally
In the Terminal app on your Mac, use the cp command to make a copy of a file.
For example, to copy a folder named Expenses in your Documents folder to another volume named Data:
% cp -R ~/Documents/Expenses /Volumes/Data/Expenses
The -R flag causes cp to copy the folder and its contents. Note that the folder name does not end with a slash, which would change how cp copies the folder.
in your case:
make sure you are providing correct path list.txt and the correct path for destiny folder, also i mentioned how to access file variable in double quotes , try this code it's working for me
for file in $(cat ~/Documents/list.txt); do cp "$file" ~/dir_newfolder; done

cp hundreds of files to different directories

The title not might be the best, I apologize, I'm rather new to scripting.
I'm trying to copy 2 files from each directory and place these compounds in a separate directory that only shares directory names.
for clarity;
/path/to/directory/all/variable_directories/
Inside this directory will be multiple files, I need 2 files which will have the same name in every individual variable directory.
I am trying to copy these 2 files from each individual variable directory and put them in variable directories based on the basename of /variable_directory/
the copy destination will be;
/path/to/magical/shit/subset/set_with_variable_name/variable_directories/
Only some of the destination directories are located in each /set_with_variable_name/
The script will need to be able to go through each /set_with_variable_name/ until it finds the directory that shares the basename of the directory that these files are originally being cp'd from
There's about 100 directories
to cp from and to and about 200 files total that need to be copied and sorted appropriately.
I can get it to cp ALL the files to the SAME directory using;
#! /usr/bin/env bash
for i in */;
do cd $i;
cp filename /path/to/destination/;
cp other_filename /path/to/destination/;
cd ..;
done;
It's the sorting the files to the correct destinations that I am completely lost at.
I appreciate any help, I'm a novice to this type of scripting
Looks like you need something like that.
# looping through all the variable directories
for var_dir in <path1>/all/*; do
# creating the destination directory if not exists
mkdir -p "<path2>/set_with_variable_name/$(basename ${var_dir})"
# copying the first file
cp "${var_dir}/filename1" "<path2>/set_with_variable_name/$(basename ${var_dir})/filename1"
# and the second
cp "${var_dir}/filename2" "<path2>/set_with_variable_name/$(basename ${var_dir})/filename2"
done

How to copy files and add prefix at the same time?

I am not familiar with osx terminal command.
I have a java project containing many package.
Some classes have same name in different package.
I need to copy all of the class files into a directory, so I need to add
corresponding package prefix on each files.
For example, I have root/com/example1/test.java and root/com/example2/test.java two classes having the same name in different packages. I need to copy them into root directory and add prefix, making them become example1.test.java and example2.test.java in root directory.
How to do this using terminal command?
This solution is not perfect but it should do what you want (assuming I understood your question correctly):
Create a file doCopy.sh with the following content:
#!/bin/bash
origName=$1
newName=$(echo $origName | sed -e 's|/|.|g')
echo cp $origName $newName
Then make it executable and call it for each of your files:
chmod +x doCopy.sh
find root -type f -exec ./doCopy.sh {} \;
Please verify the commands that will be printed. If you are satisfied you can remove the echo from doCopy.sh and rerun the find to actually copy the files.

Copying multiple files with same name in the same folder terminal script

I have a lot of files named the same, with a directory structure (simplified) like this:
../foo1/bar1/dir/file_1.ps
../foo1/bar2/dir/file_1.ps
../foo2/bar1/dir/file_1.ps
.... and many more
As it is extremely inefficient to view all of those ps files by going to the
respective directory, I'd like to copy all of them into another directory, but include
the name of the first two directories (which are those relevant to my purpose) in the
file name.
I have previously tried like this, but I cannot get which file is from where, as they
are all named consecutively:
#!/bin/bash -xv
cp -v --backup=numbered {} */*/dir/file* ../plots/;
Where ../plots is the folder where I copy them. However, they are now of the form file.ps.~x~ (x is a number) so I get rid of the ".ps.~*~" and leave only the ps extension with:
rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;
Then, as the ps files have hundreds of points sometimes and take a long time to open, I just transform them into jpg.
for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;
This is not really a working bash script as I have to change the directory manually.
I guess the best way to do it is to copy the files form the beginning with the names
of the first two directories incorporated in the copied filename.
How can I do this last thing?
If you just have two levels of directories, you can use
for file in */*/*.ps
do
ln "$file" "${file//\//_}"
done
This goes over each ps file, and hard links them to the current directory with the /s replaced by _. Use cp instead of ln if you intend to edit the files but don't want to update the originals.
For arbitrary directory levels, you can use the bash specific
shopt -s globstar
for file in **/*.ps
do
ln "$file" "${file//\//_}"
done
But are you sure you need to copy them all to one directory? You might be able to open them all with yourreader */*/*.ps, which depending on your reader may let browse through them one by one while still seeing the full path.
You should run a find command and print the names first like
find . -name "file_1.ps" -print
Then iterate over each of them and do a string replacement of / to '-' or any other character like
${filename/\//-}
The general syntax is ${string/substring/replacement}. Then you can copy it to the required directory. The complete script can be written as follows. Haven't tested it (not on linux at the moment), so you might need to tweak the code if you get any syntax error ;)
for filename in `find . -name "file_1.ps" -print`
do
newFileName=${filename/\//-}
cp $filename YourNewDirectory/$newFileName
done
You will need to place the script in the same root directory or change the find command to look for the particular directory if you are placing the above script in some other directory.
References
string manipulation in bash
find man page

Resources