Folders tree with rights - macos

In OS X and SunOS OS there is no exist the 'bash tree command'.
To plot a tree "graph" of folders i use the following instruction:
find . -type d -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
Or this to show files too.
find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
But i need another version which contains also the folders rights. Im pretty lost to add on the right side the folder rights. Anyone have any idea ??
Update:
There are any option to plot the files inside the folders and their rights too. I'm trying with this command find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g' and doing combination with the solution provided by #fedorqui but the result aren't so good.
That's the result obtained with the above command, without rights.
| | |____src
| | | |____cft2exit.c
| | | |____cft2exit_AIX
| | | |____cft2exit_SUN
| | | |____gestidt.c
| | | |____gestidt.h
| | | |____gestidt.o
| | | |____gestidt_AIX
| | | |____gestidt_SUN
| | | |____gestidt_SunOS
| | | |____makefile
| | | |____sem.a
| | | |____ut_sem.c
| | | |____ut_sem.h
| | | |____ut_sem.o
| |____data
| | |____purge.dat
| |____lost+found

You can execute ls -ld for each result of find. It will give you the permissions, other things, and then the file name. If you then pipe to awk, with awk '{print $NF, $1}' you can print both blocks of information. Finally, you pipe to your sed command. All together:
find . -type d -exec ls -ld {} \; | awk '{print $NF, $1}' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
Test
$ find . -type d -exec ls -ld {} \; | awk '{print $NF, $1}' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
. drwxrwxr-x
|____python drwxrwxr-x
| |____jinja2 drwxrwxr-x
| | |____bk drwxrwxr-x
| | |____infiles drwxrwxr-x
.......
In small steps:
$ find . -type d -exec ls -ld {} \;
drwxrwxr-x 7 me me 4096 Aug 15 15:35 .
drwxrwxr-x 3 me me 4096 Aug 13 14:31 ./python
drwxrwxr-x 4 me me 4096 Apr 26 15:14 ./python/jinja2
drwxrwxr-x 2 me me 4096 Apr 19 14:26 ./python/jinja2/bk
drwxrwxr-x 2 me me 4096 Apr 19 12:54 ./python/jinja2/infiles
and then
$ find . -type d -exec ls -ld {} \; | awk '{print $NF, $1}'
. drwxrwxr-x
./python drwxrwxr-x
./python/jinja2 drwxrwxr-x
./python/jinja2/bk drwxrwxr-x
./python/jinja2/infiles drwxrwxr-x

On OS X you can install tree, using homebrew:
brew install tree
or, using macports:
sudo port install tree
and then, to view directories with permissions:
$ tree -p -d
Sample output:
.
├── [drwxr-xr-x] folder1
│   └── [drwxr-xr-x] folder2
│   └── [drwxr-xr-x] folder3
│   └── [drwxr-xr-x] folder4
└── [drwxr-xr-x] folder5
├── [drwxr-xr-x] folder6
└── [drwxr-xr-x] folder7

Related

Moving all files from subfolders to main folders with duplicate file names

I've been trying to write a little script to sort image files in my Linux server.
I tried multiple solution found all over StackExchange but it never meets my requirements.
Explanation:
photo_folder are filled with images (various extensions).
Mostly, images are already in this folder.
But sometime, like the example below, images are hidden in one or multiple photo_subfolder and file names are often the same such as 1.jpg, 2.jpg... in each of them.
Basically, I would like to move all image files from photo_subfolder to their photo_folder and all duplicated filenames to be renamed before merging together.
Example:
|parent_folder
| |photo_folder
| | |photo_subfolder1
| | | 1.jpg
| | | 2.jpg
| | | 3.jpg
| | |photo_subfolder2
| | | 1.jpg
| | | 2.jpg
| | | 3.jpg
| | |photo_subfolder3
| | | 1.jpg
| | | 2.jpg
| | | 3.jpg
Expectation:
|parent_folder
| |photo_folder
| | 1_a.jpg
| | 2_a.jpg
| | 3_a.jpg
| | 1_b.jpg
| | 2_b.jpg
| | 3_b.jpg
| | 1_c.jpg
| | 2_c.jpg
| | 3_c.jpg
Note that files names are just an example. Could be anything.
Thank you!
You can replace the / of the subdirectories with another character, e.g. _ , and then cp/mv the original file to the parent directory.
I try to recreate an example of your directory tree here - very simple, but I hope it can be adapted to your case. Note that I am using bash.
#!/bin/bash
bd=parent
mkdir ${bd}
for i in $(seq 3); do
mkdir -p "${bd}/photoset_${i}/subset_${i}"
for j in $(seq 5); do
touch "${bd}/photoset_${i}/${j}.jpg"
touch "${bd}/photoset_${i}/${j}.png"
touch "${bd}/photoset_${i}/subset_${i}/${j}.jpg"
touch "${bd}/photoset_${i}/subset_${i}/${j}.gif"
done
done
Here is the script that will cp the files from the subdirectories to the parent directory. Basically
find all the files recursively in the subdirectories and loop on them
use sed to replace \ with '_' and store this in a variable new_filepath (I also remove the initial parent_, but this is optional)
copy (or move) the old filepath into parent with filename new_filepath
for xtension in jpg png gif; do
while IFS= read -r -d '' filepath; do
new_filepath=$(echo "${filepath}" | sed s#/#_#g)
cp "${filepath}" "${bd}/${new_filepath}"
done < <(find ${bd} -type f -name "*${xtension}" -print0)
done
ls ${bd}
If you want to remove also the additional parent_ from the new_filepath you can replace the new_filepath above with:
new_filepath=$(echo ${filepath} | sed s#/#_#g | sed s/${bd}_//g)
I assumed that you define all the possible extension in the script. Otherwise to find all the extensions in the directory tree you can use the following snippet from a previous answer
find . -type f -name '*.*' | sed 's|.*\.||' | sort -u

bash get dirname from urls.txt

$ cat urls.txt
/var/www/example.com.com/upload/email/email-inliner.html
/var/www/example.com.com/upload/email/email.html
/var/www/example.com.com/upload/email/email2-inliner.html
/var/www/example.com.com/upload/email/email2.html
/var/www/example.com.com/upload/email/AquaTrainingBag.png
/var/www/example.com.com/upload/email/fitex/fitex-ecr7.jpg
/var/www/example.com.com/upload/email/fitex/fitex-ect7.jpg
/var/www/example.com.com/upload/email/fitex/fitex-ecu7.jpg
/var/www/example.com.com/upload/email/fitex/fitex.html
/var/www/example.com.com/upload/email/fitex/logo.png
/var/www/example.com.com/upload/email/fitex/form.html
/var/www/example.com.com/upload/email/fitex/fitex.txt
/var/www/example.com.com/upload/email/bigsale.html
/var/www/example.com.com/upload/email/logo.png
/var/www/example.com.com/upload/email/bigsale.png
/var/www/example.com.com/upload/email/bigsale-shop.html
/var/www/example.com.com/upload/email/bigsale.txt
Can anyone help me to get dirname for this?
dirname /var/www/example.com.com/upload/email/sss.png works fine, but what about a list of URLs?
Is it possible to achieve this without the use of any form of a loop (for or while). As the number of URLs can be more than several tens of millions. The best way would be with the help of redirection (tee) to a file
As always when it boils down to things like this, Awk comes to the rescue:
awk 'BEGIN{FS=OFS="/"}{NF--}1' <file>
Be aware that this is an extremely simplified version of dirname and does not have the complete identical implementation as dirname, but it will work for most cases. A correct version, which covers all cases is:
awk 'BEGIN{FS=OFS="/"}{gsub("/+","/")}
{s=$0~/^\//;NF-=$NF?1:2;$0=$0?$0:(s?"/":".")};1' <file>
The following table shows the difference:
| path | dirname | awk full | awk short |
|------------+---------+----------+-----------|
| . | . | . | |
| / | / | / | |
| foo | . | . | |
| foo/ | . | . | foo |
| foo/bar | foo | foo | foo |
| foo/bar/ | foo | foo | foo/bar |
| /foo | / | / | |
| /foo/ | / | / | /foo |
| /foo/bar | /foo | /foo | /foo |
| /foo/bar/ | /foo | /foo | /foo/bar |
| /foo///bar | /foo | /foo | /foo// |
note: various alternative solutions can be found in Extracting directory name from an absolute path using sed or awk. The solutions of Kent will all work, the solution of Solid Kim just needs a tiny tweak to fix the multiple slashes (and misses upvotes!)

Script to generate a list to run a command

Sorry for the semi-vague title, I wasn't exactly sure how to word it. I'm looking to generate a list, excluding devices without a matching major/minor number, and run
lkdev -l hdiskn -a -c DATAn
where the hdisk and the DATA device having corresponding major/minor numbers.
In /dev, I have -
root# testbox /dev
#ls -l | grep -E "DATA|hdisk" | grep -v rhd
crw-r--r-- 1 root system 18, 3 Oct 03 10:50 DATA01
crw-r--r-- 1 root system 18, 2 Oct 03 10:50 DATA02
brw------- 1 root system 18, 1 Apr 12 2013 hdisk0
brw------- 1 root system 18, 0 Apr 12 2013 hdisk1
brw------- 1 root system 18, 3 Jan 14 2014 hdisk2
brw------- 1 root system 18, 2 Jan 14 2014 hdisk3
brw------- 1 root system 18, 4 Jan 14 2014 hdisk4
So essentially, I'm trying to create something where hdisk0,1,4 are all excluded, and hdisk2-3 are locked with DATA01 and DATA02, respectively.
I originally was trying to use sort and/or uniq to isolate/remove fields, but haven't been able to generate the desired list to even begin looking at running the command on each.
(As a note, I have several servers with hundreds of these. If it were just these few, I'd find a "simpler" way.)
(I can't test it right now, so please correct syntax errors if any)
You could play with sort en uniq like beneath
ls -l | grep -E "DATA|hdisk" | sed -e 's/.* \([0-9]*, *[0-9]*\).*/\1/' | sort |
uniq -c | grep -v " 1" | cut -c8- | while read majorminor; do
ls -l | grep " ${majorminor}" | sed 's/.* //'
done
However, you should start with selecting the right lines without counting:
for data in $(find /dev -type c -name "DATA*" | cut -d/ -f3); do
majorminor="$(ls -l $data | sed -e 's/.* \([0-9]*, *[0-9]*\).*/\1/')"
echo "$data <==> $(ls -l hdisk* | grep " ${majorminor}" | sed 's/.* //')"
done

find files with same names in directory

I was wondering in case I could do the following, better than what I have.
Objective: Identify files with the same name in the directory tree. I do not have any knowledge if there would be any duplicate file or the location/name of such files.
Expected output: List the files with the location.
Input provided: path of top directory for search.
My algorithm:
1.list all file in the target directory (I have used find -name ".")
2.List1: sort the file names
3.List2: Uniquify files names
4.Diff lists from step 2 & 3 to get the repeated file
5.extract the location.
Sample Directory:
temp/
|-- d1
| |-- d2
| | `-- f3
| |-- d3
| | `-- f3
| |-- f1
| `-- f2
`-- d4
|-- d5
| |-- f2
| `-- f6
|-- f4
`-- f5
> find temp/ -type f -follow -print | sed 's;.*/;;' | sort -u > ~/tmp/12
> find temp/ -type f -follow -print | sed 's;.*/;;' | sort -n > ~/tmp/11
> diff ~/tmp/11 ~/tmp/12
3,4d2
< f2
< f3
> find temp/ -name f2
temp/d1/f2
temp/d4/d5/f2
> find temp/ -name f3
temp/d1/d2/f3
temp/d1/d3/f3
I want to simplify this process. Any help would be appriciated. Please let me know in case you need further details.
Guys this is a solution that I identified fitting my needs and may help you:
Your comments are welcome.
set idirectory = `echo $* | awk '{print $1}'`
if ( -d $idirectory ) then
foreach xxx (`find $idirectory -type f -follow -print | sed 's;.*/;;' | sort -n | uniq -d`)
echo "Multiple files found for " $xxx
find $idirectory -name $xxx
end
endif

Retrieve Files along with last modified date under a directory using shell

I am trying to retrieve list of files inside a (unix) directory , I want to retrieve the files along with modified date
ls -LR retrieve the files for me , but I need the modified date alone with it how do I do it ?
Using tree
tree -D
Quoting from man tree
-D Print the date of the last modification time or if -c is used, the last status change time for the file listed.
Test
% tree -D
.
|-- [Oct 19 20:20] dir1
| |-- [Oct 19 19:49] file1
| |-- [Oct 19 19:49] file2
| `-- [Oct 19 19:49] file3
`-- [Oct 19 20:20] dir2
|-- [Oct 19 20:20] file1
|-- [Oct 19 20:20] file2
`-- [Oct 19 20:20] file3
2 directories, 6 files
Using ls followed by awk
ls -lR | awk '$9 {print $6, $7, $8, $9}'
Test
% ls -lR | awk '$9 {print $6, $7, $8, $9}'
Oct 19 19:49 file1
Oct 19 19:49 file2
Oct 19 19:49 file3
Use find -type f -printf "<whatever>" to print the file name plus modification date or anything else you want to know about the file. man find.

Resources