J'essaye d'obtenir tous les fichiers entre deux dates sur s3 -
echo "2018-01-01" | sed -n "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p" echo "2019-01-01" | sed -n "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p" echo "2019-02-01" | sed -n "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p" echo "2019-02-01" | sed -n "/2018-06-01/,/2019-01-05/p" echo "2019-06-30" | sed -n "/2018-06-01/,/2019-01-05/p"
Cela a tendance à me donner toutes les données. Utilisé mais cela ne fonctionne pas - https://stackoverflow.com/a/29412898/2251058 (ne filtrer quoi que ce soit) Est-ce une bonne façon de le faire?
Toute aide est appréciée.
Mises à jour
Comme demandé - RavinderSingh13
J'ai utilisé -n as et trouvé sans -n la commande sed agit comme une commande cat.
Comme suggéré par jhnc, j'ai ajouté -n pour l'utiliser comme commande grep et cela me donne un résultat vide
Un exemple de modèle d'entrée est quelque chose comme suit avec un résultat vide
2018-06-01 13:32:20 <filesize> <filepath>....gz . . . . 2019-02-04 00:13:12 12344 <filepath>....gz
Avec -n ajouté (à utiliser comme grep), j'ai eu un bogue ci-dessus où -n n'a pas été utilisé, il n'affiche aucune sortie. Pour vérifier, j'ai utilisé les commandes ci-dessous. Il ne donne aucune sortie.
aws s3 ls 's3://big-data-analytics-prod/LZ/copycat/emailstats/' --recursive | sed "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p"
3 Réponses :
Le code sed
donné dans la question ne fonctionnera correctement que si la date de début apparaît dans la liste.
Nous devons faire des comparaisons de chaînes plutôt que des expressions rationnelles. Soit awk, soit perl est à la hauteur de la tâche.
Perl fantaisie:
awk '$0>="2018-06-01" && $0<="2019-01-01" {print}'
Simple awk (pourrait intégrer la date d'appel de la même manière que sed d'origine) :
#!/usr/bin/perl # Usage: $0 date1 date2 # where dates can be anything supported by date(1) # remember to "quote whitespace" # fancy date parsing open(my $cmd, '-|', 'date', '+%Y-%m-%d %H:%M:%S', '--date', $ARGV[0]||'1970-01-01') or die $!; my $start = <$cmd>; chomp $start; close $cmd; open(my $cmd, '-|', 'date', '+%Y-%m-%d %H:%M:%S', '--date', $ARGV[1]||'now') or die $!; my $end = <$cmd>; chomp $end; close $cmd; # start should be earlier than end ($start, $end) = ($end, $start) if $start gt $end; while (<STDIN>) { print if $_ ge $start && $_ le $end; }
Oui, j'ai fait la même chose plus tôt, j'ai oublié de le mettre comme réponse - aws s3 ls 's3: // big-data-analytics-prod / LZ / copycat / emailstats /' --recursive | awk -v begintime = '2018-06-01' -v endtime = "` date +% Y-% m-% d -d 'il y a 30 jours'` "-v bucket =" s3: // big-data- analytics-prod / "'{if ($ 1> = beginintime && $ 1 <= endtime) {print bucket $ 4}}'
awk est préférable d'utiliser pour cela.
Pendant ce temps, j'ai appris un peu de awk et à la place, j'ai utilisé awk pour calculer cela, mais j'ai oublié de partager comme réponse.
aws s3 ls 's3://big-data-analytics-prod/LZ/copycat/emailstats/' --recursive | awk -v begintime="2018-06-01" -v endtime="`date +%Y-%m-%d -d '30 days ago'`" '{if($1>=begintime && $1<=endtime) {print $4}}'
OU dans une ligne
endtime=`date +%Y-%m-%d -d '-30 day'` begintime="2018-06-01" bucket="s3://big-data-analytics-prod/" path='s3://big-data-analytics-prod/LZ/copycat/emailstats/' aws s3 ls path --recursive | awk '{if($1>=$begintime && $1<=$endtime) {print $4} }'
En guise de solution simple (sans sed), essayez ce qui suit:
#!/bin/bash # usage: thiscommand startdate enddate # starddate and enddate should be in the format: yyyy-mm-dd start=${1//-/} end=${2//-/} while read -r date rest; do date2=${date//-/} if ((start <= date2 && date2 <= end)); then echo "$date $rest" fi done < <(aws s3 ls 's3://big-data-analytics-prod/LZ/copycat/emailstats/' --recursive)
où le fichier d'exemple input.txt
ressemble à: p >
2019-01-01 01:23:45 <filesize> <filepath>....gz 2019-01-30 00:22:45 <filesize> <filepath>....gz 2019-02-01 11:03:05 <filesize> <filepath>....gz 2019-02-02 02:24:55 <filesize> <filepath>....gz
Appelez ensuite le script avec:
$ ./thisscript 2019-01-01 2019-02-02
renvoie:
2018-06-01 13:32:20 <filesize> <filepath>....gz 2019-01-01 01:23:45 <filesize> <filepath>....gz 2019-01-30 00:22:45 <filesize> <filepath>....gz 2019-02-01 11:03:05 <filesize> <filepath>....gz 2019-02-02 02:24:55 <filesize> <filepath>....gz 2019-02-04 00:13:12 12344 <filepath>....gz
Si vous souhaitez traiter directement la sortie de la commande aws
, vous pouvez dire:
#!/bin/bash # usage: thiscommand startdate enddate # starddate and enddate should be in the format: yyyy-mm-dd start=${1//-/} end=${2//-/} while read -r date rest; do date2=${date//-/} if ((start <= date2 && date2 <= end)); then echo "$date $rest" fi done < input.txt
Vous verrez qu'il n'y a pas d'astuce: c'est juste convertit le format de la date en nombres simples et les compare arithmétiquement.
Agréable. Si nous utilisons bash, les s ///
ne sont pas nécessaires comme nous pouvons le faire ["$ start" \ <"$ date2"] && ["$ date2" \ < "$ end"]
directement (bien que cela changera la plage sélectionnée sauf si nous testons également =
qui annule l'enregistrement de caractères!)
Absolument. Merci de me rappeler que nous pouvons effectuer une comparaison de l'ordre du dictionnaire sans déhyphation. J'ai peut-être été pris dans le concept de conversion en valeurs numériques.
Veuillez mentionner la sortie de la commande
aws s3 ls 's3: // big-data-analytics-prod / LZ / copycat / emailstats /' --recursive
et mentionnez également la sortie de l'échantillon attendu car ce n'est pas le cas clair.@ RavinderSingh13 Ajout d'un exemple de sortie. Faites-moi savoir si quelque chose d'autre est nécessaire. Fondamentalement, j'utilise la date de aws s3 ls (liste des fichiers) à grep
Vous pouvez remplacer
sed
parsort | sed -n
. Et je suppose que vous savez que vous n'obtiendrez que le premier fichier de la date de fin. Et pour être complet, commencez chaque//
par^
@jhnc La commande ls est triée dans ce cas. J'ai essayé avec
sed -n
cela donne des résultats vides à la fois valides et invalidesecho "2018-08-30" | sed -n "/ 2018-06-01 /, /` date +% Y-% m-% d -d 'il y a 30 jours'` / p "
echo" 2018-06-30 " | sed -n "/ 2018-06-01 /, /` date +% Y-% m-% d -d 'il y a 30 jours'` / p "
Je viens de réaliser: cela ne fonctionnera pas si la date de début n'apparaît pas dans la liste