Create a directory list printer - linux

On Windows there are many programs that can recursively print a detailed list of directory contents. I haven't found any for Linux and so I'm trying to create a script that does so.
This is what I'm going for:
For each file print full path name(Tab)size in Mb(Tab)file extension
If there are several directories, skip a line for each different directory traversed.
For the directory name, print the directory name and leave blank-spaced tabs for extension and size.
Sample output is as follows:
Path and Name Size MiB Extension
C:\Users\xxx\Desktop\beers\
C:\Users\xxx\Desktop\beer1\- random name.pdf 5.11 pdf
C:\Users\xxx\Desktop\beer1\- random name2.djvu 5.11 djvu
C:\Users\xxx\Desktop\beer2\
C:\Users\xxx\Desktop\beer2\- random name.mp4 253.91 mp4
Based on a user comment and some research, I have:
ls -R -lh /mnt/folder300/ | cut -d' ' -f 5- > folder300.txt
With this, I intend to take the output of ls -R -lh and omit the first 4 fields.
But, I notice this clips text for example on nested directories. What am I doing wrong?

This bash command give size and full path
find ~+ -type f -maxdepth 100 -exec du -bh {} ;

Related

Find -perm finds file (or something else) that dosent exist

Hello i am new in the world of linux and i have a simple question:
I created a directory named testfiles and 10 textfiles inside of it with various permissions.
I tried using find -perm -u=wr | wc -l in order to count all files with rw prem for user but it counts 1 more file than it is supposed to have. I then used find -perm -u=wr to see the list and realized there is an extra line in the beginning which i am not sure what it is can someone help? How do I get rid of that?
The '.' and '..' are references to the current directory and the parent directory respectively. These exist in all linux directories. As these are treated as directories, you can ignore them by using the '-type' option of the find command, where 'f' specifies files only.
find -perm -u=wr -type f | wc -l
Note that the find command as you have it will recursively find files if another directory exists where you are running the command. You can limit it to the current directory only by using the max depth option. Run 'man find' in the terminal to see all the other options you have with the find command.

How to copy desired log file content when logs are frequently being rotated in Linux

Suppose some logs is being rotated by size 50MB each .
I did 'grep' some string and my string is present in log file, log_3 and I want to copy content of log_3 before it gets rotated(renamed) to log_4 .
Please suggest how to take backup of content of log_3 before it is rotated .
I just need the content of log_3 . I don't want like I copied log_3 (by cp -p log_3 log_3_backup) but by that time logs got rotated and now log_3_backup contains content of log_2 .Is there any way we can do to avoid this . Working on an automation project I need a solution to this . Thank you very much for your suggestions in advanced . You May share python or shell script .
You can get the file inode number that won't change if renamed, then reference the file by that name
for f in *.log; do
# get inode of file
iname=$(ls -i $f)
# test file contents for pattern presence
if grep -q 'some pattern' $f; then
# the file contains the searched pattern, let's do something
# find by inode number and move it
find -inum $iname -exec mv {} {}.bak ';'
fi
done
Perhaps getting a backup of the file is not necessary anymore, let's grep it again
find -inum $iname -print0 | xargs -r0 grep 'some pattern'

Retrieving the sub-directory, which had most recently been modified, in a Linux shell script?

How can I retrieve the sub-directory, which had most recently been modified, in a directory?
I am using a shell script on a Linux distribution (Ubuntu).
Sounds like you want the ls options
-t sort by modification time, newest first
And only show directories, use something like this answer suggests Listing only directories using ls in bash: An examination
ls -d */
And if you want each directory listed on one line (if your file/dirnames have no newlines or crazy characters) I'd add -1 So all together, this should list directories in the current directory, with the newest modified times at the top
ls -1td */
And only the single newest directory:
ls -1td */ | head -n 1
Or if you want to compare to a specific time you can use find and it's options like -cmin -cnewer -ctime -mmin -mtime and find can handle crazy names like newlines, spaces, etc with null terminated names options like -print0
How much the subdirectory is modified is irrelevant. Do you know the name of the subdirectory? Get its content like this:
files=$(ls subdir-name)
for file in ${files}; do
echo "I see there is a file named ${file}"
done

Searching a directory for files

Hi all I am trying to write a script which recursively searches directories from a parent directory and counts how many text files (.txt) are in the sub directories. I also need to output the files relative path to the parent directory.
Lets say I have a folder named Files
Within this folder there may be:
Files/childFolder1/child1.txt
Files/childFolder1/child2.txt
Files/childFolder1/child3.txt
Files/childFolder2/child4.txt
Files/childFolder2/child5.txt
Files/child6.txt
So the output would be
The files are:
/childFolder1/child1.txt
/childFolder1/child2.txt
/childFolder1/child3.txt
/childFolder2/child4.txt
/childFolder2/child5.txt
/child6.txt
There are 6 files in the 'Files' folder
So far I have a script which is this:
#! /bin/csh
find $argv[1] -iname '*.txt'
set wc=`find $argv[1] -iname '*.txt' | wc -l`
echo "Number of files under" $argv[1] "is" $wc
I have no idea how to make the output so it only shows the file path relative to the directory. Currently my output is something like this:
/home/Alice/Documents/Files/childFolder1/child1.txt
/home/Alice/Documents/Files/childFolder1/child2.txt
/home/Alice/Documents/Files/childFolder1/child3.txt
/home/Alice/Documents/Files/childFolder2/child4.txt
/home/Alice/Documents/Files/childFolder2/child5.txt
/home/Alice/Documents/Files/child6.txt
Number of files under /home/Alice/Documents/Files is 6
Which is not desired. I am also worried about how I am setting the $wc variable. If the directory listing is large then this is going to acquire a massive overhead.
cd $argv[1] first and then use find . -iname '*.txt' to make the results relative to the directory
Try
find $argv[1] -iname '*.txt' -printf "%P \n"
This should give the desired output :)
Hayden
Also, if you don't want to execute find twice, you can either:
store its output in a variable, though I don't know if variables are limited in size in csh ;
store its output in a temporary file, but purists don't like temporary file;
count the number of lines yourself in a while loop which iterates over the results of find.
Note that if you used bash instead, which supports process substitution you could duplicate find's output and pipe it to multiple commands with tee:
find [...] | tee >(cmd1) >(cmd2) >/dev/null

How to recursive list files with size and last modified time?

Given a directory i'm looking for a bash one-liner to get a recursive list of all files with their size and modified time tab separated for easy parsing. Something like:
cows/betsy 145700 2011-03-02 08:27
horses/silver 109895 2011-06-04 17:43
You can use stat(1) to get the information you want, if you don't want the full ls -l output, and you can use find(1) to get a recursive directory listing. Combining them into one line, you could do this:
# Find all regular files under the current directory and print out their
# filenames, sizes, and last modified times
find . -type f -exec stat -f '%N %z %Sm' '{}' +
If you want to make the output more parseable, you can use %m instead of %Sm to get the last modified time as a time_t instead of as a human-readable date.
find is perfect for recursively searching through directories. The -ls action tells it to output its results in ls -l format:
find /dir/ -ls
On Linux machines you can print customized output using the -printf action:
find /dir/ -printf '%p\t%s\t%t\n'
See man find for full details on the format specifiers available with -printf. (This is not POSIX-compatible and may not be available on other UNIX flavors.)
find * -type f -printf '%p\t%s\t%TY-%Tm-%Td %Tk:%TM\n'
If you prefer fixed-width fields rather than tabs, you can do things like changing %s to %10s.
I used find * ... to avoid the leading "./" on each file name. If you don't mind that, use . rather than * (which also shows files whose names start with .). You can also pipe the output through sed 's/^\.\///'.
Note that the output order will be arbitrary. Pipe through sort if you want an ordered listing.
You could try this for recursive listing from current folder called "/from_dir"
find /from_dir/* -print0 | xargs -0 stat -c “%n|%A|%a|%U|%G” > permissions_list.txt

Lists files and directories passes through to stat command and puts all the info into a file called permissions_list.txt
“%n|%A|%a|%U|%G” will give you the following result in the file:
from_
 dir|drwxr-sr-x|2755|root|root
from_dir/filename|-rw-r–r–|644|root|root

Cheers!


Resources