how to get number of files older than 1 hour on ksh HP-UX - find

I need to list set of files created older than 1 hour in certain folder of HP-UX. Following is the command i tried.
find . -type f -mmin +60 | wc -l
But it return following error for ksh
find: bad option -mmin
What is the alternative option to get number of files older than 1 hour?
Even i tried following command. Still another error. But it also work on bash
find . -type f -mtime +0.04 | wc -l
find: Error in processing the argument 0.04

find in HP-UX has no options for minutes, mtime takes days as argument.
You can create a testfile, "touch" it with the desired time and then compare with ! -newer[m]. For instance:
# onehourago=`date +"%m %d %H %M" | awk '{ onehourago=$3 - 1 ; if (onehourago<0) { onehourago=59 } printf("%.2d%.2d%.2d%.2d\n",$1,$2,onehourago,$4) }'`
# touch -t "$onehourago" testfile
# find . -type f ! -newer testfile | wc -l

Related

Issue with Sed no input file when Xgrep

I am trying to create a script which looks for x days old files that have a specific string in it, it then removes it and logs the file it has changed.
My way is probably not the best way, but I am new to this so looking for some help. I have got to a stage where the script works but it does not log the file name it has worked on
Working script is
find /home/test -mtime +5 -type f ! -size 0 | xargs grep -E -l '(abc_Pswd_[1-9])' | xargs -n1 sed -i '/abc_Pswd_[1-9].*/d'
I am trying to get the file name from 2nd part of the script I have tried few things
find /home/test -mtime +7 -type f ! -size 0 | xargs grep -E -l '(abc.1x.[1-9] )' > /home/test/tst.log| xargs -n1 sed -i '/abc_Pswd_[1-9].*/d'
This works in terms of logging the result but it exits with the error "sed: no input files"

Shell Script While Loop and Perl Printing Extra Line

I modified a script which a poster gave me from another board to better suit my needs. InputConfig.txt contains directories to find files in, the inbound file age (second column) and the outbound file age (third column). These inbound/outbound numbers for each directory don't have to be the same, I just made them so. Most important is VI and AB directories have specific age to check against, everything else uses the generic 30 minutes.
Perl statement purpose is to capture the timestamp of each file found. The problem is the printf is putting an extra line because the while loop is reading 3 lines but I only need the 2 lines (or however many) to print.
I don't know Perl well enough to fix it - if the problem is with Perl.
Appreciate the help.
InputConfig.txt
/home/MF/NA/CD 30 30
/home/MF/NA/CD/VI 10 10
/home/MF/NA/CD/AB 15 15
Script
#!/bin/ksh
VI=*/CD/VI/*
AB=*/CD/AB/*
cat InputConfig.txt | while read DIR IT OT; do
TS=$(find "${DIR}" -type f -path "${DIR}/*/inbound/*" -mmin "+${IT}" ! -path "${VI}" ! -path "${AB}")
TS=$(find "${DIR}" -type f -path "${DIR}/*/outbound/*.done" -mmin "+${OT}")
TS=$(find "${DIR}" -type f -path "${DIR}/inbound/*" -mmin +"${IT}")
perl -e 'printf("%s,%d\n", $ARGV[0], (stat("$ARGV[0]"))[9]);' "$TS"
done
Output:
,0
/home/MF/NA/CD/VI/inbound/vis,1492716168
/home/MF/NA/CD/AB/inbound/abc,1492716485
Desired Output
/home/MF/NA/CD/VI/inbound/vis,1492716168
/home/MF/NA/CD/AB/inbound/abc,1492716485
The script has many problems:
it assigns 3x in row the TS variable, so, only the last one will be used. The first two runs of the find is pointless - so probably you want achieve something else.
youre getting the mtime using perl. It is cool idea if you will read the filenames from the stdin and not starting perl X times. In such case will be faster to use the stat shell command - with other words, you want read the filenames from the stdin.
always use read -r (unless you know why do not want the -r) :)
useless use of cat. Just redirect the whole loop input from a file
So, the script could probably looks like:
#!/bin/ksh
VI=*/CD/VI/*
AB=*/CD/AB/*
while read -r DIR IT OT; do
find "${DIR}" -type f -path "${DIR}/*/inbound/*" -mmin "+${IT}" ! -path "${VI}" ! -path "${AB}" -print
find "${DIR}" -type f -path "${DIR}/*/outbound/*.done" -mmin "+${OT}" -print
find "${DIR}" -type f -path "${DIR}/inbound/*" -mmin +"${IT}" -print
done < InputConfig.txt | perl -lne 'printf "%s,%d\n", $_, (stat($_))[9];'
This is more ksh and/or shell question as perl. :)
If I have well understood, you want to use perl to display the name and the size of the files found by previous find commands. Something like that should work:
#!/bin/ksh
VI=*/CD/VI/*
AB=*/CD/AB/*
cat InputConfig.txt | while read DIR IT OT; do
(find "${DIR}" -type f -path "${DIR}/*/inbound/*" -mmin "+${IT}" ! -path "${VI}" ! -path "${AB}" ;
find "${DIR}" -type f -path "${DIR}/*/outbound/*.done" -mmin "+${OT}" ;
find "${DIR}" -type f -path "${DIR}/inbound/*" -mmin +"${IT}") |
xargs -l perl -e 'printf("%s,%d\n", $ARGV[0], (stat("$ARGV[0]"))[9]);'
done
Thanks everyone for your input but I went back to my original if-else method of script since my TIBCO project from which I am calling the script was not liking the output format.
My script, invoked like ./CDFindFiles /home/NA/CD/:
#!/bin/ksh
FOLDER=$1
VI=*/CD/VI/inbound
AB=*/CD/AB/inbound
find "$FOLDER" -type f -path "${FOLDER}*/inbound/*" -o -path "${FOLDER}*/outbound/*.done" | while read line;
do
MODTIME=$(perl -e 'printf "%d\n",(-M shift)*24*60' "$line")
if [[ "$line" == *"$VI"* && "$MODTIME" -gt 90 || "$line" == *"$AB"* && "$MODTIME" -gt 180 ]]; then
perl -e 'printf("%s,%d\n", $ARGV[0], (stat("$ARGV[0]"))[9]);' "$line"
elif [[ "$line" != *"$VI"* && "$line" != *"$AB"* && "$MODTIME" -gt 30 ]]; then
perl -e 'printf("%s,%d\n", $ARGV[0], (stat("$ARGV[0]"))[9]);' "$line"
fi
done

ls: terminated by signal 13 when using xargs

I'm using the following command to delete four largest size files in a folder:
find "/var/www/site1/" -maxdepth 1 -type f | xargs ls -1S | head -n 4 | xargs -d '\n' rm -f
It works fine, but from time to time throws broken pipe error:
xargs: ls: terminated by signal 13
I ran across a similar issue and found this thread on search for an answer:
Signal 13 means something is written to a pipe where nothing is read from anymore (e.g. see http://people.cs.pitt.edu/~alanjawi/cs449/code/shell/UnixSignals.htm ).
The point here is that the ls command as executed by xargs is still writing output when the following head command already got all the input it wants and closed its input-pipe. Thus it's safe to ignore, yet it's ugly. See also the accepted answer in https://superuser.com/questions/554855/how-can-i-fix-a-broken-pipe-error
You are purposely terminating your program with head -n 4, which creates the broken pipe because you terminated it before the "caller" finished. Since this is expected by you, you can ignore the error by redirecting it to /dev/null which discards it:
find "/var/www/site1/" -maxdepth 1 -type f | xargs ls -1S | head -n 4
| xargs -d '\n' rm -f 2>/dev/null
I got the same error, "terminated by signal 13", under different circumstances and other answers here helped me work out the fix. I'd like to expand on the nature of the problem:
corpy386 ~/gw/Release/5.1_v9/ClaimCenter $ find . -name '*.pcf' -not -name '*build*' | xargs grep -l ClaimSnapshotGeneralPanelSet | ( read f && echo $f && grep 'def=' $f )
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
xargs: grep: terminated by signal 13
So here's the same error and I'd only get a single line of output when I knew there are numerous files that match what I'm looking for. The problem was that xargs is producing multiple lines of output and read is only consuming a single line before ending. xargs tries to write the rest of its results to one of the pipes but the receiving end has already quit and gone home. Hence, signal 13: Broken Pipe.
The fix was to consume all of xargs's output by looping - change read f && do_some_things (which reads one time only) to while read f; do do_some_things; done.
corpy386 ~/gw/Release/5.1_v9/ClaimCenter $ **find . -name '*.pcf' -not -name '*build*' | xargs grep -l ClaimSnapshotGeneralPanelSet | while read f; do echo $f; grep 'def=' $f; done**
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.gl.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Pr.pcf
def="ClaimSnapshotGeneralPRPanelSet(Claim, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Trav.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.wc.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotLossDetailsScreen.default.pcf
def="ClaimSnapshotGeneralPanelSet(Claim, SnapshotParam)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.gl.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Pr.pcf
def="ClaimSnapshotGeneralPRPanelSet(Claim, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Trav.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.wc.pcf
def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotLossDetailsScreen.default.pcf
def="ClaimSnapshotGeneralPanelSet(Claim, SnapshotParam)"
This isn't exactly the same situation as OP's script - They wanted a part of the input and cut it off on purpose, I wanted the whole stream and cut it off by accident - but the shell semantics work out the same. Programs tend to be written to keep running until they have consumed all their input rather than test to see if their recipient is still listening.

How to get files which are created one hour ago in solaris 5.9

I want to get files which are created one hour ago, i tried following command
/usr/bin/find /home/FILES/ -name '*.xml' -atime +.0417 -exec ls -l{} \;
In the above command .0417 is (1 day /24 hours ).
The find command which i am using does not have -mmin option.
Is there a way to get files created less one hour ago.
set the file time to 1 hours ago
touch -t 201410042236 /tmp/hourold.tmp;
/usr/bin/find /home/FILES/ -name '*.xml' /tmp/hourold -type f -exec ls -l {} \;

find command for the newest 500 files in a directory tree and also be POSIX compliant

I'm looking for a single line shell script or unix command to find the newest 500 files in a directory tree. Major constraints are it should be POSIX compliant and the directory can have tons of files.
I found from the below link a perl script which helped:
find . -type f -print | perl -l -ne ' $_{$_} = -M; END { $,="\n"; print sort {$_{$b} <=> $_{$a}} keys %_ }' | head -n 500
How to recursively find and list the latest modified files in a directory with subdirectories and times?
Any more comments most welcome.Thanks all.
How about this:
Posix ls and head
ls -tc DIR | head -n 500
find . -type f -print | perl -l -ne ' ${$} = -M; END { $,="\n"; print sort {${$b} <=> ${$a}} keys %_ }' | head -n 500
It should be the contrary for the sort ${$a} <=> ${$b}
The head can be avoided: print+(...)[0..499]
The find too with a recursive call:
perl -e 'sub R{($_)=#_;map{-d$_?&R($_):$_}<$_/*>}print$_,$/for(sort{-M$a<=>-M$b}R".")[0..499]'
Or with an unix cmd: not sure if there are to many arguments may fail
find . -type f -exec ls -1t {} + | head -500
find . -type f -print0 | xargs -0 ls -1t | head -500
find . -type f -exec stat -c %Y:%n {} \; |
sort -rn | sed -e 's/.*://' -e 500q
This sorts on ctime, which can be changed by using %Z or %X in the format string, but stat is not POSIX.
There is no 100% reliable POSIX way of doing this with shell scripting.
A POSIX C program will do it easily though, assuming you define newest by either last modified file content or last changed file. If you mean last creation time, there is no POSIX way and possibly no solution at all, depending on the file system used.