免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2308 | 回复: 6
打印 上一主题 下一主题

[Linux] 如何在有中文的记录中进行分隔,并返回指定列的值?谢谢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-07-29 22:14 |只看该作者 |倒序浏览
大家好!

最近编写一个Shell脚本,希望能从文本文件中按照ID(第一列)找到记录后,返回对应列的值(列从1开始计算)。

文本文件内容如下:
1234567890        国有企业A        湖南省        长沙市        岳麓区        1992-01-28
0987654321        合资企业B        湖北省        武汉市        东湖区        1993-03-01
1029384756        外资企业C        江苏省        徐州市        中心区        1990-01-01

每个列均由tab分隔(已经在Notepad++中进行了查看)。

但是发现,如果存在中文(如以上数据),那么代码执行会出错,如:
通过1234567890找到第一行,返回企业名称,正确情况应该是:国有企业A,但是返回的却是:
国有企业A 湖南省 长沙市
而且期间的tab键也变成了空格键。

但是如果将其中的中文全部用英文替代,则可以正常返回:guoyouA。
如将以上内容修改为:
1234567890        guoyouA        hunan        changsha        yuelu        1992-01-28
0987654321        heziB        hubei        wuhan        donghu        1993-03-01
1029384756        waiziC        jiangsu        xuzhou        zhongxin        1990-01-01

貌似是中文的问题,不知道如何解决?请高人不惜赐教。谢谢!

以下是相关代码:
  1. 18 #函数说明:从文本文件中(每条记录一行)返回对应下标的值(下标从1开始)的值。
  2. 19 #参数说明:
  3. 20 #   $1 -- 需要查找字段值的记录;
  4. 21 #   $2 -- 记录字段分隔符;
  5. 22 #   $3 -- 返回值下标(从1开始)
  6. 23 #举例:splitStr2 "you   are the best" " " 2,将返回are。
  7. 24 #Creator: Colin
  8. 25 #Date: 2016-07-28
  9. 26 function splitStr2()
  10. 27 {
  11. 28     str_to_split="$1"
  12. 29     delimiter="$2"
  13. 30     arrIndex="$3"
  14. 31
  15. 32     pointer=`expr index "${str_to_split}" "${delimiter}"`
  16. 33     counter=1
  17. 34     while [[ ${pointer} -gt 0  ]]
  18. 35         do
  19. 36             if [ ${counter} == ${arrIndex} ]; then
  20. 37                 echo ${str_to_split:0:$[${pointer}-1]}
  21. 26 function splitStr2()
  22. 27 {
  23. 28     str_to_split="$1"
  24. 29     delimiter="$2"
  25. 30     arrIndex="$3"
  26. 31
  27. 32     pointer=`expr index "${str_to_split}" "${delimiter}"`
  28. 33     counter=1
  29. 34     while [[ ${pointer} -gt 0  ]]
  30. 35         do
  31. 36             if [ ${counter} == ${arrIndex} ]; then
  32. 37                 echo ${str_to_split:0:$[${pointer}-1]}
  33. 38                 return;
  34. 39             fi
  35. 40
  36. 41             ((counter++))
  37. 42             str_to_split=${str_to_split:${pointer}}
  38. 43             pointer=`expr index "${str_to_split}" "${delimiter}"`
  39. 44         done
  40. 45
  41. 46     if [ $counter == $arrIndex  ]; then
  42. 47         echo "${str_to_split}"  
  43. 48     fi
  44. 49 }
  45. 50
  46. 51 #函数说明:从文本文件中(每条记录一行)返回对应下标的值(下标从1开始)的值。
  47. 52 #参数说明:
  48. 53 #   $1 -- 文本文件路径;
  49. 54 #   $2 -- 查找关键词;
  50. 55 #   $3 -- 记录字段分隔符;
  51. 56 #   $4 -- 返回值下标(从1开始)
  52. 57 #   $5 -- first:表示如果搜索出多行记录,则以第一行记录对应值为准。
  53. 58 #举例:
  54. 59 #Creator: Colin
  55. 60 #Date: 2016-07-28
  56. 61 function getFieldValueFromLineRecordTxtFile()
  57. 62 {
  58. 63     rowNum=`cat $1 | grep $2 | wc -l`
  59. 64
  60. 65     if [ ${rowNum} -eq 0 ]; then
  61. 66         #如果没有找到任何记录;
  62. 67         echo "No records matched."
  63. 68         return;
  64. 69     elif [ ${rowNum} -eq 1 ]; then
  65. 70         #如果查到了唯一的记录;
  66. 71         record=`cat $1 | grep $2`
  67. 72         value=`splitStr2 "${record}" "$3" $4`
  68. 73         echo "${value}"
  69. 74         return;
  70. 75     elif [ ${rowNum} -gt 1 -a $5 = "first" ]; then
  71. 76         #如果查找到多行记录,并且模式为“以第一行记录为准”;
  72. 77         record = `cat $1 | grep $2 | head -n 1`
  73. 78         value = `splitStr2 "${record}" "$3" $4`
  74. 79         echo "${value}"
  75. 80         return;
  76. 81     else
  77. 82         echo "Found ${rowNum} record(s) and the mode is NOT first!"
  78. 83         return;
  79. 84     fi
  80. 85 }
  81. 86
  82.     #调用(myTestData_TabSplit.txt 包含了以上展示的文本记录内容)
  83. 87 getFieldValueFromLineRecordTxtFile "/home/training/fujun/testTabSplitter/myTestData_TabSplit.txt" "1234567890" "    " 3 "single"
复制代码

论坛徽章:
0
2 [报告]
发表于 2016-07-29 22:47 |只看该作者
补充一下Linux系统版本信息:
CentOS release 6.3 (Final)

论坛徽章:
0
3 [报告]
发表于 2016-07-30 13:12 |只看该作者
有人知道吗????

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2016-07-30 17:44 |只看该作者
回复 1# colinFu88


    这个就应该直接上 awk

论坛徽章:
0
5 [报告]
发表于 2016-07-30 20:10 |只看该作者
回复 4# MMMIX

感谢回复。能给个例子么?谢谢!

   

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
6 [报告]
发表于 2016-07-30 22:31 |只看该作者
本帖最后由 MMMIX 于 2016-07-30 22:31 编辑

回复 5# colinFu88


    awk '/^0987654321/ { print $2 }' data.txt

论坛徽章:
0
7 [报告]
发表于 2016-07-31 15:53 |只看该作者
谢谢!搞定。
MMMIX 发表于 2016-07-30 22:31
回复 5# colinFu88
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP