CSV가 있고 7일보다 오래된 모든 행을 삭제해야 합니다. 이것은 csv 형식입니다.
개인 ID VIP CS SS LT FTLT PS 수정 날짜 스탬프 T001028 1 1 1 0 0 0 05-07-2013 T001250 1 1 1 0 0 0 08-05-2012 T001261 1 1 1 0 0 1 2013년 4월 4일 T001345 1 1 1 0 0 0 2013년 4월 3일 T078503 1 1 1 0 0 0 04-03-2013 T079819 1 1 1 0 0 1 2013년 3월 22일 T080119 1 1 1 0 0 1 2013년 4월 2일 T090574 1 1 1 0 0 0 2012년 11월 15일 T091106 1 1 1 0 0 1 2013년 3월 22일
수정된 날짜 열의 형식은 MM/DD/YYYY입니다. 어떤 아이디어라도 좋습니다. RedHat 5 Linux 시스템에서 작업을 수행하려고 합니다.
답변1
tail
date -d ...
, awk
및 Bash 기능을 사용하는 방법은 다음과 같습니다 .
tail -n+2 file.csv | {
while read line ; do
tmstmp=$(echo "$line" | awk '{print $8}');
[ $(( $(date -d "now" +%s) - $(date -d "$tmstmp" +%s) )) -lt $(( 60*60*24*7 )) ] && echo "$line";
done;
}
어떻게 작동하나요?
위 코드는 파일의 행을 구문 분석 file.csv
하고 8번째 열(날짜)을 가져온 다음 에포크 이후의 초 수와 구문 분석된 날짜 사이의 델타를 계산합니다. 7일 초 미만이면 행이 인쇄됩니다.
디버그
무슨 일이 일어나고 있는지 디버깅하기 위해 이 줄을 넣을 수 있습니다. tmpstmp=...
다음 줄 뒤에 넣으세요 .
echo "TMSTMP: $tmstmp" "TMDELTA: $(( $(date -d "now" +%s) - $(date -d "$tmstmp" +%s) ))" "TMWINDOW: $(( 60*60*24*7 ))"
예
간단하게 유지하기 위해 위의 내용을 스크립트에 넣고 이름을 지정했습니다 rprttime.bash
.
#!/bin/bash
tail -n+2 file.csv | {
while read line ; do
tmstmp=$(echo "$line" | awk '{print $8}');
echo "TMSTMP: $tmstmp" "TMDELTA: $(( $(date -d "now" +%s) - $(date -d "$tmstmp" +%s) ))" "TMWINDOW: $(( 60*60*24*7 ))"
[ $(( $(date -d "now" +%s) - $(date -d "$tmstmp" +%s) )) -lt $(( 60*60*24*7 )) ] && echo "$line";
done;
}
이제 실행하면:
$ ./rprttime.bash
TMSTMP: 05/07/2013 TMDELTA: 5157421 TMWINDOW: 604800
TMSTMP: 08/05/2012 TMDELTA: 28917421 TMWINDOW: 604800
TMSTMP: 04/04/2013 TMDELTA: 8008621 TMWINDOW: 604800
TMSTMP: 04/03/2013 TMDELTA: 8095021 TMWINDOW: 604800
TMSTMP: 04/03/2013 TMDELTA: 8095021 TMWINDOW: 604800
TMSTMP: 3/22/2013 TMDELTA: 9131821 TMWINDOW: 604800
TMSTMP: 04/02/2013 TMDELTA: 8181421 TMWINDOW: 604800
TMSTMP: 11/15/2012 TMDELTA: 20101021 TMWINDOW: 604800
TMSTMP: 3/22/2013 TMDELTA: 9131821 TMWINDOW: 604800
기간을 7일에서 60일로 변경하고 디버그 줄을 비활성화하면 다음 줄이 인쇄되는 것을 볼 수 있습니다.
$ date
Fri Jul 5 16:49:19 EDT 2013
$ ./rprttime.bash
T001028 1 1 1 0 0 0 05/07/2013
답변2
또 다른 유한 포크 답변
많이 있기 때문에포크그것을 채찍질하고 가지고세게 때리다이를 수행하는 방법은 sed
1개의 포크만 사용합니다 /bin/date
.
sedstr=""
{
i=1;
read now;
while read line;do
((i++));
[ $(( (now-line) /86400 )) -gt 143 ] && sedstr="${i}d;$sedstr"
done
}< <(
sed -ne $'s/^.*[ \t,]//g;y|-|/|;/[0-9]$/p;1inow' < file.tsv |
date -f - +%s
)
sed -e "$sedstr" < file.tsv
Person ID VIP CS SS LT FTLT PS Modified Datestamp
T001028 1 1 1 0 0 0 05-07-2013
T001261 1 1 1 0 0 1 04-04-2013
T001345 1 1 1 0 0 0 04-03-2013
T078503 1 1 1 0 0 0 04-03-2013
마지막 명령은 콘솔에 출력하는 대신 제자리에서 수정하는 sed
데 사용할 수 있습니다 .-i
echo $sedstr
10d;9d;8d;7d;3d;
sed -e $sedstr -i file.tsv
cat file.tsv
Person ID VIP CS SS LT FTLT PS Modified Datestamp
T001028 1 1 1 0 0 0 05-07-2013
T001261 1 1 1 0 0 1 04-04-2013
T001345 1 1 1 0 0 0 04-03-2013
T078503 1 1 1 0 0 0 04-03-2013
답변3
awk를 호출하기 전에 이러한 행을 무시해야 하는 날짜를 계산하는 경우 다음을 수행할 수 있습니다.
awk -v cmpdate=20130628 '{line=$0; dateval=$8;FS="/"; $0=dateval;
thisdate=$3*10000+$1*100+$2; if (thisdate>cmpdate) print line; FS=" ";}' file
편집 1:
FS
마지막으로 원래 값으로 재설정됩니다. 한 줄의 입력만으로 코드를 테스트했는데 아무런 차이가 없었습니다.
답변4
Perl을 사용하여 이 작업을 수행하겠습니다(터미널에서 실행).
$ perl -lane 'BEGIN{$date=`date +%s`; chomp($date)}
if($.==1){print}
else{
$F[$#F]=~s/-/\//g;
$fdate=`date -d "$F[$#F]" +%s`;
chomp($fdate);
print if $date-$fdate<604800;
}' file.csv
스크립트는 오늘 날짜를 계산하여 작동합니다.에포크 이후 초그런 다음 각 행의 날짜를 동일한 형식으로 변환하고 오늘 날짜에서 뺀 후 7일 미만인 경우에만 인쇄합니다(7*24*60*60=604800).
노트
스크립트는 몇 초 안에 실행되는데 이는 귀하의 아이디어에 비해 너무 정확할 수 있습니다. 그렇다면 알려주시면 일일 수준에서 작동하도록 수정하겠습니다.
또한 입력 파일이 동형 형식인 경우에는 필요하지 않을 수도 있지만 게시한 예제에서는 필요하므로 즉시 변환 중입니다
MM-DD-YYYY
.MM/DD/YYYY