Assign the name of the Folder to the name of a file - shell

I would like to paste a number of files in a unique file named, for example, "output.txt".
Nevertheless I would like to assign the name of the folder to the name of the output file so that it will be: "output_<name of the Folder>.txt".
I have thousands of folders so that the "paste" command will run in a for loop I'm able to write. Can anyone help me please?

The question is incredibly unclear. I'm going to interpret it to mean that you have a large number of directories that all contain a file named 'output.txt', and you want to move those files to a single directory with the original path embedded in the name. Assuming that the root of the directory tree containing all the files is /path/to/source and you want to move them to /path/to/destination:
find /path/to/source -name output.txt -exec sh -c 'd=$(dirname "$1" |
tr / _); cp "$1" "/path/to/destination/output_$d.txt"' sh {} \;
Relative paths will work fine as well as absolute paths.

I too am unclear about what you want, but mktemp(1) has TEMPLATES which might help.

Related

find path of files from a list of filenames and display it

I have a file named "file.txt" which contains several filenames like this :
filename1.ext
filename2.ext
filename3.ext
filename4.ext
I want to find these files through the directory /home (And so all the sub-directories of the directory etc etc..) [I assume I will have to use the find command from the shell], display the name of the file if the directory contains it and the associated path.
The file "file.txt" will be passed as an argument so the command should be ./find_path.sh file.txt
Thank you in advance for your help !
I would do this: build up an array holding the arguments you give to find
find_args=("-false")
while read -r file; do
find_args+=("-o" "-name" "$file");
done < "$1"
find /home "${find_args[#]}"
That gives you the flexibility to add further directives, for example if you want to change the output:
find /home "${find_args[#]}" -printf '%f\t%h\n' | sort -k 1,1

Bash copy files recursively exclude list of some files

Try to copy files recursively from directory (d1) to directory (d2) exclude some files and folders using lists:
filepaths to exclude stored as files.txt
and directories list to exlude stored as dirs.txt.
Already read some SOF articles like
Copy folder recursively, excluding some folders
BASH copy all files except one
tried rsync
rsync -avr --exclude=*/exclude_filename_* d1/ d2/
but wildcards don't suit either due to a large number of different file names.
Maybe I have to use WHILE loop with rsync..? Still looking for solution.
Does anybody know how to do this?
This is not the best way to do it, but if rsync is not working, you can use find to composite a list and then remove files from that list.
find . -name "*" | grep -v "<filename you dont want>" | xargs -i cp --parents {} /output/dir/name
The only thing to keep in mind here is that your current directory must be the base directory of the files you want to copy, in order to preserve the parent structure.
note:
Add another | grep -v "<filename you dont want>" to remove a second file. Alternatively, you can use wildcard matching in one grep grep -v "<file1>\|<file2>"

How to move files based on file names in a.csv doc - macOS Terminal?

Terminal noob need a little help :)
I have a 98 row long filename list in a .csv file. For example:
name01; name03, etc.
I have an external hard drive with a lot of files in chaotic file
structure. BUT the file names are consistent, something like:
name01_xy; name01_zq; name02_xyz etc.
I would like to copy every file and directory from the external hard
drive which begins with the filename stored in the .csv file to my
computer.
So basically it's a search and copy based on a text file from an eHDD to my computer. I guess the easiest way to do is a Terminal command. Do you have any advice? Thanks in advance!
The task can be split into three: read search criteria from file; find files by criteria; copy found files. We discuss each one separately and combine them in a one-liner step-by-step:
Read search criteria from .csv file
Since your .csv file is pretty much just a text file with one criterion per line, it's pretty easy: just cat the file.
$ cat file.csv
bea001f001
bea003n001
bea007f005
bea008f006
bea009n003
Find files
We will use find. Example: you have a directory /Users/me/where/to/search and want to find all files in there whose names start with bea001f001:
$ find /Users/me/where/to/search -type f -name "bea001f001*"
If you want to find all files that end with bea001f001, move the star wildcard (zero-or-more) to the beginning of the search criterion:
$ find /Users/me/where/to/search -type f -name "*bea001f001"
Now you can already guess what the search criterion for all files containing the name bea001f001 would look like: "*bea001f001*".
We use -type f to tell find that we are interested only in finding files and not directories.
Combine reading and finding
We use xargs for passing the file contents to find a -name argument:
$ cat file.csv | xargs -I [] find /Users/me/where/to/search -type f -name "[]*"
/Users/me/where/to/search/bea001f001_xy
/Users/me/where/to/search/bea001f001_xyz
/Users/me/where/to/search/bea009n003_zq
Copy files
We use cp. It is pretty straightforward: cp file target will copy file to directory target (if it is a directory, or replace file named target).
Complete one-liner
We pass results from find to cp not by piping, but by using the -exec argument passed to find:
$ cat file.csv | xargs -I [] find /Users/me/where/to/search -type f -name "[]*" -exec cp {} /Users/me/where/to/copy \;
Sorry this is my first post here. In response to the comments above, only the last file is selected likely because the others have a carriage return \r. If you first append the directory to each filename in the csv, you can perform the move with the following command, which strips the \r.
cp `tr -d '\r' < file.csv` /your/target/directory

Move and rename files based on subfolders

I would appreciate any help, relatively new here
I have the following directory structure
Main_dir
|-Barcode_subdirname_01\(many further subfolders)\filename.pdf
|-Barcode_subdirname_02\(many further subfolders)\filename.csv
There are 1000s of files within many subfolders
The first level sub directories have the barcode associated to all files within. eg 123456_dirname
I want to copy all files within all subfoders to the main_dir and
rename the files subdirname_barcode_filename.extension (based only on the first subdirectory name and barcode)
I've been attempting to write a bash script to do this from the main_dir but have hit the limit of my coding ability (i'm open to any other way that'll work).
firstly identifying the first level sub folders
find -maxdepth 1 -type d |
then cut out the first 2 parts deliminated by the underscores
cut -d\_ -f1 > barcode
then find the files within the subfolders, rename and move
find -type f -print0 |
while IFS= read -r filenames; do
newname="${barcode/sudirname/filename\/}"
mv "filename" "main_dir"/"newname"
done
I can't get it to work and may be headed in the wrong direction.
You can use rename with sed like substitute conventions, for example
$ rename 's~([^_]+)_([^_]+)_.*/([^/.]+\..*)~$1_$2_$3~' barcode_subdir_01/a/b/c/file2.csv
will rename file to
barcode_subdir_file2.csv
I used ~ instead of the more common / separator to make it more clear.
You can test the script with -n option to show the renamed files without actually doing the action.

Bash script to transverse a directory

I have a directory with XML files and other directories. All other directories have XML files and subdirectories, etc.
I need to write a script (bash probably) that for each directory runs java XMLBeautifier directory and since my skills at bash scripting are a bit rubbish, I would really appreciate a bit of help.
If you have to get the directories, you can use:
$ find . -type d
just pipe this to your program like this:
$ find . -type d | xargs java XMLBeautifier
Another approach would be to get all the files with find and pipe that to your program like this:
$ find . -name "*.xml" | xargs java XMLBeautifier
This takes all .xml files from the current directory and recursively through all subdirectories. Then hands them one by one over with xargs to java XMLBeautifier.
Find is an awesome tool ... however, if you are not sure of the file name but have a vague idea of what those xml file contains then you can use grep.
For instance, if you know for sure that all your xml files contains a phrase "correct xml file" (you can change this phrase to what you feel appropriate) then run the following at your command line ...
grep -IRw "correct xml file" /path/to/directory/*
-I option searches the file and returns the file name when pattern is matched
-R option reaches your directory recursively
-w ensure that the pattern given matches on the whole and not single word individually
Hope this helps!

Resources