find main directory name which doesn't contains file in sub directory - linux

I have three folders as test1, test2,test3. under these three folders i have two folders as common dir1,dir2 . Each of the above three parent folders will have these two as sub folders. I will have one text file (file.txt) in dir1 in any one of the parent directory.
Is there a find or grep single line command to get the parent directory name as output if file.txt doesn't exists in dir1 sub folder?
Example:
ls test1
o/p: dir1, dir2
ls test2
o/p: dir1/file.txt,dir2
ls test3
o/p: dir1/file.txt,dir2
i need a command which gives test1 as output

something like below should do what you need :
for f in test*/dir1/
do
[[ $(find "$f" -name "file.txt") ]] || echo `dirname "$f"`
done

Related

How to match partly matching filenames from two directories and execute commands on what found

I'm trying to match two directories and if the file exists in the second directory, I want to move files from the first directory to a third one.
The filenames do not matching exactly, they get a "_ica" at the end of the name and a different extension.
I have tried to write a script that loops through dir1 checks if it's in dir2
and if found move to dir3:
DATA= /home/eegfilesonlyWM/*
PROCESSED= /home/eegfilesonlyWM/icaddata/*
DONE= /home/eegfilesonlyWM/done/
for f in $DATA ; do
fname=${f##*/}
fname=${fname%/}
find /home/eegfilesonlyWM/icaddata/ -iname "${fname*_ica*}" -type f -exec mv {} ./done \;
done
I would like to copy from the first directory those files that already have corresponding files in the second directory.
Thank you for any help
Maybe this will do what you want:
#!/usr/bin/env bash
#Directory paths here
DATA=./DATA
PROCESSED=./PROCESSED
DONE=./DONE
#Do the test and copy here
for f in `ls -1 $DATA`; do
#build output name
p="$PROCESSED/${f/\.xxx/}"; #xxx is the file extension of original
p="${p}_ica.yyy"; #yyy is the file extension of the processed
if [ -f $p ] ; then
cp $DATA/$f $DONE
fi
done

Merge multiple files in multiple directories - bash

We have a requirement to loop multiple directiories and in each directory there will be, multiple text files with Pattern File"n".txt which needs to merged to one, File.txt
We are using Bourne Shell scripting.
Example:
/staging/dusk/inbound/ --> Main Directory
Dir1
File1.txt,File2.txt,..sample1.doc,sample2.pdf,File*.txt --> we have to Merge the File name which starts with Fil*.txt -->Final.txt
Dir2
File1.txt,File2.txt,..attach1.txt,sample1.doc, File*.txt --> we have to Merge the File name which starts with Fil*.txt -->Final.txt
Dir3
File1.txt,File2.txt,File*.txt,..sample1,sample2*.txt --> we have to Merge the File name which starts with Fil*.txt -->Final.txt
Dir4
File1.txt,File2.txt,File*.txt,..temp.doc,attach.txt --> we have to Merge the File name which starts with Fil*.txt -->Final.txt
Di5
File1.txt,File2.txt,File*.txt,..sample1,sample2*.txt --> we have to Merge the File name which starts with Fil*.txt -->Final.txt
Dir"n"
File1.txt,File2.txt,File3.txt,File*.txt..attach1,attach*.txt --> we have to Merge the File name which starts with Fil*.txt -->Final.txt
The files from each directory can be looped using
cat *.txt > all.txt command.
But how we loop the directiories?
To catenate Fil*.txt from all immediate subdirectories of the current directory,
cat */Fil*.txt >Final.txt
To access arbitrarily deeply nested subdirectories, some shells offer ** as an extension, but this is not POSIX sh -compatible.
cat **/Fil*.txt >Final.txt
If you actually want to loop over your directories and do something more complex with each, that's
for d in */; do
: something with "$d"
done
Or similarly, for shells which support **, you can loop over all directories within directories;
for d in **/; do
: something with "$d"
done
For example, : something with "$d" could be cat "$d"/Fil*.txt >"$d"/Final.txt to create a Final.txt in each directory, which contains only the Fil*.txt files in that directory.
You can do it in a ad-hok way
find /staging/dusk/inbound -type f -name *.txt | sort -n | awk '{ print "cat " $1 " >> all.txt"}' > marge.sh
chmod +x marge.sh
sh merge.sh
you can probably try using the find command
find /staging/dusk/inbound/ -name "*.txt" -type f -exec cat {} \;>>MergedFile.txt

Copy files from multiple folders with including folder name in Linux

I have multiple sub folders e.g.:
ls ./
F1 F2 F5 F8 F12 ...
Each folder contain file "file.txt"
How to copy all file.txt files to main folder containing folder name?
cp ./F1/file.txt ./file_1.txt
cp ./F2/file.txt ./file_2.txt
...
Perl One Liner
first go to main folder than:
find . | perl -a -F/ -lne 'qx(cp -r "$F[1]" T/ )'
note
do not worry about log file on the screen if would be!
T/
is your target directory
main folder
Where all your file exist. If your all file is in the folder Music for example; so cd Music then that Perl One Liner
declare -a dirs
i=1
for d in */
do
dirs[i++]="${d%/}"
done
echo "There are ${#dirs[#]} dirs in the current path"
for((i=1;i<=${#dirs[#]};i++))
do
echo "Copying file.txt from ${dirs[i]} dir..."
cp ./${dirs[i]}/file.txt ./file_$i.txt
done
Save it as a script file, fileTxtCopy.sh, for instance. Then place it at the parent dir and give it executable permission sudo chmod +x fileTxtCopy.sh.
Run it as script and you should have all your file.txt file copied in parent dir.
Copies file.txt files from each folder inside a current directory to the current directory and appends numbers contained in a folder name to the name of the copied file.
for i in *; do a=$(<<< "$i" grep -o "[0-9]*" -); cp "$i/file.txt" "file_$a.txt"; done
Not the most robust approach though.

Linux: How to move files with same name, diff ext. into their own folder?

I have files like this
This list is a sample of my files note the actual files are not in sucessive order.
file1.a
file2.a
file1.b
file2.b
...
and some have a .c extension but not all
How would I move these files into their own named folder.
I have tried this
find . -type f -print0 | xargs -0 -l sh -c 'mkdir "${1%.*}" && mv "$1" "${1%.*}"' sh
but it doesn't work as intended i.e. Well it creates the folders but wont put the second file of same name different extension in the same folder.
mkdir: cannot create directory ‘./file1’: File exists
mkdir: cannot create directory ‘./file2’: File exists
mkdir: cannot create directory ‘./file3’: File exists
You should use mkdir -p, it won't complain (and break the &&) if directories exist (it will also create parent directories if those don't exist).
for FILE in $(ls file[0-9].[a-z])
do
DIRNAME=$(echo $FILE |cut -c1-5)
[ -d $DIRNAME ] || mkdir $DIRNAME
mv ${FILE}* $DIRNAME
done
This will give you:
$ ls file1 file2
file1:
file1.a file1.b file1.c
file2:
file2.a file2.b file2.c

Shell Script for renaming and relocating the files

I am working on something and need to solve the following. I am giving a analogous version of mine problem.
Say we have a music directory, in which there are 200 directories corresponding to different movies. In each movie directory there are some music files.
Now, say a file music.mp3 is in folder movie.mp3 . I want to make a shell script such that it renames the file to movie_music.mp3 and put it in some folder that I mention to it. Basically, all the files in the subdirectories are to be renamed and to be put in a new directory.
Any workaround for this?
This script receives two arguments: the source folder and the destination folder. It will move every file under any directory under the source directory to the new directory with the new filename:
#!/bin.sh
echo "Moving from $1 to $2"
for dir in "$1"/*; do
if [ -d "$dir" ]; then
for file in "$dir"/*; do
if [ -f "$file" ]; then
echo "${file} -> $2/`basename "$dir"`_`basename "${file}"`"
mv "${file}" "$2"/`basename "$dir"`_`basename "${file}"`
fi
done
fi
done
Here is a sample:
bash move.sh dir dir2
Moving from dir to dir2
dir/d1/f1 -> dir2/d1_f1
dir/d1/f2 -> dir2/d1_f2
dir/d2/f1 -> dir2/d2_f1
dir/d2/f2 -> dir2/d2_f2
Bash:
newdir=path/to/new_directory;
find . -type d |while read d; do
find "$d" -type f -maxdepth 1 |while read f; do
movie="$(basename "$d" |sed 's/\(\..*\)\?//')"
mv "$f" "$newdir/$movie_$(basename $f)";
done;
done
Assuming the following directory tree:
./movie1:
movie1.mp3
./movie2:
movie2.mp3
The following one-liner will create 'mv' commands you can use:
find ./ | grep "movie.*/" | awk '{print "mv "$1" "$1}' | sed 's/\(.*\)\//\1_/'
EDIT:
If your directory structure contains only the relevant directories, you can expand use the following grep instead:
grep "\/.*\/.*"
Notice it looks file anything with at least one directory and one file. If you have multiple inner directories, it won't be good enough.

Resources