getting list of top space consuming files and remove it - xargs

I am using du -hsx * | sort -rh | head -10 to get top 10 space consuming files in directory. So I would like to know how to pass output of above command and delete those files. I know about xargs but I don't know how to incorporate it in my command, so any help would be appreciated ?
Thanks

You can do something like this:
du -sxh * | sort -rh | head -10 | xargs rm -fr $1

You can do,
du -sxh * | sort -rh | head -10 > out
cat out | xargs rm -fr $1

Related

How to display the tail of multiple files in bash

I am trying to monitor the progress of the newest five files and I want to see the last few lines of the each of them.
I was able to get the newest five files using the command:
ls *.log -lt | head -5
but I want to iterate through these five files and display the last 10 lines of each file. I was wondering if it can be done in a single bash command instead of a loop. But if it can't be done, I would appreciate a bash loop implementation too
tail can take multiple file names.
tail -n 10 $(ls -t *.log | head -5)
Add -F to monitor them continuously for changes.
If the file names might have spaces xargs will be more robust:
ls -t *.log | head -5 | xargs -d '\n' tail -n 10
Assuming the file names and path names do not contain special characters such as TAB or newline, how about:
while true; do
find . -type f -name "*.log" -printf "%T#\t%p\n" | sort -n | tail -5 | cut -f2 | xargs tail -10
sleep 1
done
ls *.log -1t | head -5 | while IFS= read -r file; do tail -10 "$file"; done

Count the number of files that modified in specif range of time [duplicate]

This question already has an answer here:
Getting all files which have changed in specific time range
(1 answer)
Closed 3 years ago.
I'm trying to build a one-line command in bash which counts the number of files of type *.lu in the current directory that were modified between 15:17 and 15:47 (date does not matter here). I'm not allowed to use find (otherwise it would been easy). I'm allowed to use basic commands like ls, grep, cut, wc and so on.
What I tried to do:
ls -la *.lu | grep <MISSING> | wc -l
First of all, I'll find all files *.lu, than I need to check with grep the date (which I'm not sure how to do) and than we need to count the number of lines. I think we need to insert also cut to get to the date and check it, but how? Also if current directory does not have *.lu files it will fail rather than returning 0.
How to solve it?
ls -l *.lu | grep -E '15:[2-3][0-9]|15:1[7-9]|15:4[0-7]' | wc -l
Should do it.
With awk:
ls -al *.lu | awk 'BEGIN{count=0} {if((substr($8,0,2) == "15") && (int(substr($8,4)) >=17 && int(substr($8,4)) <= 47 )){count++}} END{print count}'
UPDATE:
Without -E
ls -l *.lu | grep '15:[2-3][0-9]\|15:1[7-9]\|15:4[0-7]' | wc -l
Redirect error in case of zeros files:
ls -l *.lu 2> /dev/null | grep '15:[2-3][0-9]\|15:1[7-9]\|15:4[0-7]' | wc -l
This is pretty ugly and can probably be done better. However, I wanted to challenge myself to do this without regexes (excepting the sed one). I don't guarantee it'll handle all of your use cases (directories might be an issue).
ls -l --time-style="+%H%M" *.lu 2>/dev/null |
sed '/total/d' |
tr -s ' ' |
cut -d ' ' -f6 |
xargs -r -n 1 -I ARG bash -c '(( 10#ARG >= 1517 && 10#ARG <= 1547)) && echo ARG' |
wc -l
There is probably a way to avoid parsing ls via stat --format=%Y.

Largest file in the system and move it in unix

I am new to bash and im struggling with it. I have an assignment which the question is
Try to find that top 5 larger files in the entire file system ordered by size and move the file to /tmp folder and rename the file with current datetime format
I tried with the following code
du -a /sample/ | sort -n -r | head -n 5
Im getting the list, but i cannot able to move..
Suggestions please
Looks like a simple case of xargs:
du -a /sample/ | sort -n -r | head -n 5 | xargs -I{} mv {} /tmp
xargs here simply reads lines from standard input and appends them as arguments to the command, mv in this case. Because the -I{} is specified, the {} string is replaced for the argument by xargs. So mv {} /tmp is executed as mv <the first file> /tmp and mv <the second file> /tmp and so on. You can ex. add -t option to xargs or ex. add echo to see what's happenning: xargs -I{} -t echo mv {} /tmp.
Instead of running 5 processes, we could add /tmp on the end of the stream and run only one mv command:
{ du -a /sample/ | sort -n -r | head -n 5; echo /tmp; } | xargs mv
or like:
du -a . | sort -n -r | head -n 5 | { tee; echo /tmp; } | xargs mv
Note that using du -a will most probably not work with filenames with special characters, spaces, tabs and newlines. It will also include directories in it's output. If you want to filter the files only, move to much safer find:
find /sample/ -type f -printf '%s\t%p\n' | sort -n -r | cut -f2- | head -n5 | xargs -I{} mv {} /tmp
First we print each filename with it's size in bytes. Then we numerically sort the stream. Then we remove the size, ie. cut the stream on first '\t' tabulation. Then we get the head -n5 lines. Lastly, we copy with xargs. It will work for filenames not having special characters in filenames, like unreadable bytes, spaces, newlines and tabs.
For such corner cases it's preferred to use find and handle zero terminated strings, like this (note simply just -z and -0 options added):
find /sample/ -type f -printf '%s\t%p\0' | sort -z -n -r | cut -z -f2- | head -z -n5 | xargs -0 -I{} mv {} /tmp

Bash ls and command pipe

I'm trying to use the /etc/passwd file to list home directories of users in the system, sorted and without repetitions, such that nonexisting directories would not be printed..
This is my command:
cut -f 6 -d ':' /etc/passwd | sort -su | ls -ld
It acts as if I just ran ls -ld with no arguments from the command pipe at all.
You can't pipe stuff into ls.. You could do something like:
ls -ld $(cut -f 6 -d ':' /etc/passwd | sort -su)
By spawning a new bash to execute the cut | sort and passing it as a ls argument
ls does not take piped output. You could, however, use forward quotes to execute it on a list of directories:
ls `cut -f 6 -d ':' /etc/passwd | sort -su `
You could use xargs
cut -f 6 -d ':' /etc/passwd | sort -su | xargs ls
You were not far away, it was enough to add a xargs before ls :
cut -f 6 -d ':' /etc/passwd | sort -u | xargs ls -ld

i want to move only temp files from those top 60 file to some folder

du -mx --exclude='.snapshot' | sort -n -r|head -n 60
after the execution of this command I am getting list of 60 files out of 1000 files which are present in that folder, where I want to move only temp files from those top 60 file to some folder. I tried with below command but its not working.
du -mx --exclude='.snapshot' | sort -n -r|head -n 60 | cp *temp /mnt/TEST/
Try the following
du -mx --exclude='.snapshot' | sort -n -r | head -n 60 | grep temp | xargs cp {} /mnt/TEST/
I'm not what your files names look like, so I put in a grep on temp. You should modify that as needed.
Once it works, you will need to replace cp with mv.

Resources