开发者

Store and query a mapping in a file, without re-inventing the wheel

If I were using Pyt开发者_开发知识库hon, I'd use a dict. If I were using Perl, I'd use a hash. But I'm using a Unix shell. How can I implement a persistent mapping table in a text file, using shell tools?

I need to look up mapping entries based on a string key, and query one of several fields for that key.

Unix already has colon-separated records for mappings like the system passwd table, but there doesn't appear to be a tool for reading arbitrary files formatted in this manner. So people resort to:

key=foo
fieldnum=3
value=$(cat /path/to/mapping | grep "^$key:" | cut -d':' -f$fieldnum)

but that's pretty long-winded. Surely I don't need to make a function to do that? Hasn't this wheel already been invented and implemented in a standard tool?


Given the conditions, I don't see anything hairy in the approach. But maybe consider awk to extract data. awk approach allows for picking only the first, or the last entry, or imposing any arbitrary additional conditions:

value=$(awk -F: "/^$key:/{print \$$fieldnum}" /path/to_mapping)

Once bundled in a function it's not that scary:)

I'm afraid there's no better way at least within POSIX. But you may also have a look at join command.


Bash supports arrays, which is not exactly the same. See for example this guide.

area[11]=23
area[13]=37
area[51]=UFOs
echo ${area[11]}


See this LinuxJournal article for Bash >= 4.0. For other versions of Bash you can fake it:

hput () {
  eval hash"$1"='$2'
}

hget () {
  eval echo '${hash'"$1"'#hash}'
}

# then
hput a blah
hget a   # yields blah


Your example is one of several ways to do this using shell tools. Note that cat is unnecessary.

key=foo
fieldnum=3
filename=/path/to/mapping
value=$(grep "^$key:" "$filename" | cut -d':' -f$fieldnum)

Sometimes join comes in handy, too.

AWK, Python, Perl, sed and various XML, JSON and YAML tools as well as databases such as MySQL and SQLite can also be used, of course.

Without using them, everything else can sometimes be convoluted. Unfortunately, there isn't any "standard" utility. I would say that the answer posted by pooh comes closest. AWK is especially adept at dealing with plain-text fields and records.


The answer in this case appears to be: no, there's no widely-available implementation of the ‘passwd’ file format for the general case, and wheel re-invention is necessary in each case.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜