【问题标题】:Shell sorting with specific format具有特定格式的外壳排序
【发布时间】:2018-03-26 15:21:23
【问题描述】:

我的数据库是这种格式的,我需要按第 6 列排序。

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

(注意第 6 列的 T)

到目前为止,我已经尝试过,通过sort -M,特别是sort -k 6M -t "|" "file.dat"sort -k6 -M -t "|" 等。

由此产生的所需排序输出

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

一定是这个

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

【问题讨论】:

  • 请将该示例输入的所需输出添加到您的问题中。
  • 显示您如何将给定日期A 指定为另一个给定日期B
  • @RomanPerekhrest 可能日期 A 2010-02-15T09:33:33.400+0000 ,因为它也没有指定给我们,所以日期 B 2010-03-16T20:20:20.300+0000跨度>
  • @Cyrus 是的,我的错,我做到了
  • 如果有日期2010-01-01T09:33:33.400+0000怎么办?会计到您给定的日期2010-02-15T09:33:33.400+0000

标签: bash shell sorting awk


【解决方案1】:

最后,我看不出这个任务有什么特别之处——只是简单的排序:

sort -k6,6 -t "|" 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

【讨论】:

  • 谢谢,虽然我认为需要 -M 选项。
  • -M 用于月份排序,而不是整个日期时间
【解决方案2】:

添加了一些额外的数据行以使搜索示例更易于查看:

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

我将使用以下输入参数定义一个 bash 脚本 [search.sh]:

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

实际脚本:

$ 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]}" :将我们的 bash 变量传递给 awk 脚本;为简单起见,我们将保持相同的名称
  • -F "|" : 为 awk 定义输入字段分隔符
  • $6&gt;=dateA &amp;&amp; $6&lt;=dateB :仅打印 field6 介于(包括)我们的搜索日期之间的行

脚本的一些示例运行:

# 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

【讨论】:

  • 你是一个救星,虽然它非常适合小型数据库,但当我处理大文件时它不能正常工作。我应该检查更复杂的东西,比如编译器还是 shell 实例/版本?
  • 你必须扩展评论“它不像它应该的那样工作”;此外,如果您通常搜索(相对)少量的行,那么如果您先执行awk 工作,然后将输出通过管道传输到sort,它应该会更有效率(最终结果是您将花费更少的资源对较小的数据集进行排序)
  • 需要考虑的其他事项...如果您总是按 field6 对该文件进行排序...考虑对其进行一次排序并将结果保存到一个新文件中,然后针对新的 /已排序的文件(即消除重复排序原始文件的开销)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多