2017-10-14 4 views
0

Je me donne une base de données qui est structuré dans ce formatbase de données Tri par colonne Date/Shell

10027|Chen|Ning|female|1982-12-08|2010-02-22T17:59:59.221+0000|1.2.9.86|Firefox 
10995116908|Chen|Wei|female|1985-08-02|2010-05-2420:52:26.582+0000|27.98.244.108|Firefox 

(notez le T dans la 6e colonne)

Ma tâche est de produire le lignes de la base de données avec des dates à partir d'un donné dateA à un autre donné dateB. Jusqu'ici, j'ai essayé de trier mon fichier par la 6ème colonne avec le tri -M et plus précisément sort -k 6M -t "|" "file.dat" ou sort -k6 -M -t "|" et d'autres essais.

Mais rien ne se passe.

J'ai besoin du tri donc je peux spécifier le début et la fin avec awk

EDIT exemple La sortie de tri souhaité dans cette

933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
4194|Do|Hα» ChΓ­|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 

doit être ce

8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
4194|Do|Hα» ChΓ­|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
+0

Veuillez ajouter la sortie désirée pour cet exemple d'entrée à votre question. – Cyrus

+0

montrez comment spécifiez * une date donnéeA à une autre date donnéeB * – RomanPerekhrest

+0

@RomanPerekhrest date proprement A 2010-02-15T09: 33: 33.400 + 0000, puisqu'elle ne nous a pas été spécifiée, à ce jourB 2010-03-16T20 : 20: 20.300 + 0000 –

Répondre

1

Finalement, je ne vois rien de spécial dans cette tâche - juste un simple tri:

sort -k6,6 -t "|" file.dat 

La sortie:

8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
4194|Do|Hα» ChΓ­|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
+0

Merci travaillé, même si je pensais que -M option était nécessaire. –

+0

'-M' est pour le tri par mois, pas pour tout le temps – RomanPerekhrest

0

ajouté quelques lignes de données supplémentaires pour faire des exemples de recherche un peu plus facile à voir:

933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
4194|Do|H? Ch?|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
4567|Kim|Lisa|female|1982-05-29|2009-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
1234|Axe|John|male|1982-05-29|2012-02-21T08:44:41.479+0000|14.103.81.196|Firefox 

Je vais définir un script bash [search.sh] avec les paramètres d'entrée suivants:

search.sh [--born_after <dateA>] [--born_before <dateB>] -f <dbfile> 

`--born_after <dateA>` : [optional] search for data records with field6 >= this search parameter; [format=YYYY-MM-DDTHH:MM:SS.sss+HHMM] [default=0000-00-00T00:00:00.000+0000] 
`--born_before <dateB>` : [optional] search for data records with field6 <= this search parameter; [format=YYYY-MM-DDTHH:MM:SS.sss+HHMM] [default=9999-99-99T99:99:99.999+9999] 
`-f <dbfile>`   : [required] data file to search 

Le script réel:

$ cat search.sh 
#!/bin/bash 

# set default search dates, clear the dbfile variable: 

dateA="0000-00-00T00:00:00.000+0000" 
dateB="9999-99-99T99:99:99.999+9999" 

unset dbfile 

# simulate getopts so we can parse for long and short option names 

while [ $# -gt 0 ] 
do 
     case $1 in 
       --born-after) dateA=$2         ; shift ;; 
       --born-before) dateB=$2         ; shift ;; 
       -f)    dbfile=$2         ; shift ;; 
       *)    echo "Unexpected argument '$1'. Aborting." ; exit 1 ;; 
     esac 

     shift 
done 

# if we didn't get receive/parse a `-f <dbfile>` option then abort: 

[[ "${dbfile}" = '' ]] && echo "Missing a dbfile. Aborting." && exit 1 

# start by sorting dbfile using RomanPerekhrest's solution; then pipe results to 
# an awk script to handle the 'search' 

sort -k6,6 -t "|" ${dbfile} | awk -F"|" -v dateA="${dateA}" -v dateB="${dateB}" '$6>=dateA && $6<=dateB' 
  • -v date[AB]="${date[AB]}": passer nos variables bash dans le script awk; Par souci de simplicité, nous allons garder les mêmes noms
  • -F "|": définir séparateur de champ d'entrée pour awk
  • $6>=dateA && $6<=dateB: seulement des lignes d'impression où field6 est entre (inclus) Nos dates recherche

Quelques exemples de parcours de la script:

# no search dates provided (ie, use defaults; display entire file (sorted)) 
$ search.sh -f file.dat 
4567|Kim|Lisa|female|1982-05-29|2009-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
4194|Do|H? Ch?|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
1234|Axe|John|male|1982-05-29|2012-02-21T08:44:41.479+0000|14.103.81.196|Firefox 

# only print records (sorted) with field6 >= 2009-10-01 
$ search.sh --born-after '2009-10-01T00:00:00.000+0000' -f file.dat 
8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
4194|Do|H? Ch?|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
1234|Axe|John|male|1982-05-29|2012-02-21T08:44:41.479+0000|14.103.81.196|Firefox 

# only print records (sorted) with field6 between 2009-10-01 and 2011-05-05 
$ search.sh --born-after '2009-10-01T00:00:00.000+0000' --born-before '2011-05-05T23:59:59.999+9999' -f file.dat 
8698|Liu|Chen|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox 
1129|Lepland|Carmen|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer 
8333|Wang|Chen|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer 
933|Perera|Mahinda|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox 
4194|Do|H? Ch?|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer 
+0

Vous êtes un sauveur, et même si cela fonctionne parfaitement pour les petites bases de données, quand je gère de gros fichiers, il ne fonctionne pas comme il le devrait. Dois-je vérifier des choses plus compliquées comme le compilateur ou l'instance shell/version? –

+0

Vous devriez développer le commentaire "ça ne marche pas comme il se doit"; De plus, si vous recherchez normalement un nombre (relativement) réduit de lignes, cela devrait être un peu plus efficace si vous effectuez le travail 'awk' en premier, avec la sortie puis piped à' sort' (le résultat net est que vous – markp

+0

quelque chose d'autre à considérer ... si vous êtes toujours en train de trier ce fichier par field6 ... envisagez de le trier une fois et d'enregistrer les résultats dans un nouveau fichier, puis exécutez vos recherches sur le nouveau fichier/trié (c.-à-d. éliminer le surcoût du tri répétitif du fichier original) – markp