admin管理员组

文章数量:1530986

2024年7月19日发(作者:)

【例1】

配置文件:

xmlns:launcher="/apk/res/er"

>

launcher:className="ppWidgetProvid

er"

launcher:screen="3"

launcher:spanY="2" />

launcher:className="WidgetProvid

er"

launcher:screen="3"

launcher:spanY="1" />

launcher:className="rActivity"

launcher:screen="3"

launcher:y="3" />

launcher:className="tivity"

launcher:screen="3"

launcher:y="3" />

launcher:className="idgetProvider"

launcher:screen="4"

launcher:spanY="2" />

launcher:className="ppWidgetProvider"

launcher:screen="4"

launcher:spanY="2" />

需要在脚本中找到指定的className 如:tivity,修改其所在

段的launcher:y属性;

之前是现学修改单行文本,搞个这种不知道怎么处理了;哪位大侠帮忙分析一下怎么处理

网上回答:

方案(1)

可以试试下面的命令:

1. sed

'/^[[:space:]]*launcher:className="tivity"$/{n;n;s

/launcher:y="[^"]*"/launcher:y="XX"/}'

复制代码

大概解释下:首先是匹配launcher:className=="tivity" ,

不知道这行前有没有空格或制表符所以加上了[[:space:]]

然后{n;n;s/launcher:y="[^"]*"/launcher:y="XX"/} ,n为将匹配行的下一行加

入到模式空间,所以加上了两个n,直接到匹配行的第二行,s替换不多说了,要说明下"[^"]"

这个:只是要确保"值",这个值没有",但如果楼主觉得没必要判断,那也没什么必要,直接

y=.* /> 就好了。但如果我们要修改这个值,我觉得判断一下准确些

方案(2)

想到个不是很严谨的

1. sed '/className="tivity"/{:a;n;s/(launcher:y=).

* /1xxx /;tb;ba;:b}'

复制代码

xxx为要修改的launcher:y属性

【例2】shell sed命令修改键值对以及修改值

1.如需要修改如下键值对

sed命令:

sed

's#CERT_PATH.*$#CERT_PATH" value="/opt/SUR/ReportServer/bin/workspace/c

onf/DPIConfig"/>#g'

解释:

sed 's#键.*$#需要修改的内容(它会从键后面的全部替换也就是【的】)#g'

注意有些特殊字符需要用“”转义字符匹配。

2.修改IP地址

sed -i 's/SMM_BOARD_IP=[0-9]*.[0-9]*.[0-9]*.[0-9]*/SMM_BOARD_IP=修改后的值/g'

文件路径

3.修改数值

sed -i 's/SMM_BOARD_SNMP_Port=[0-9]*/SMM_BOARD_SNMP_Port=修改后的值

/g' 文件路径

4.修改字符串

sed -i 's/SMM_BOARD_SNMP_Port=[a-zA-Z]*/SMM_BOARD_SNMP_Port=修改后的值

/g' 文件路径

注:有时候使用命令修改,在控制台可以看到修改了,但是实际进入文件查看,没有修改,

此时要先把文件另存为,然后移除原来的文件,最后再把另存为的文件改为原来的文件名

如:

先另存为文件:sed

's|CERT_PATH.*$|CERT_PATH" value="/opt/SUR/ReportServer/bin/workspace/co

nf/DPIConfig"/>|g' >

移除原来的文件:

rm -f

再把另存为的文件改为原来的文件名:

mv

【例3】shell,sed修改指定位置的文本中的指定内容

/b/xx 即在目录b下存在一个文件xx,文件xx的内容如下

123224rsiskd1

sdfkldsfjkslf2

fdsjlfjlsdf3

fdjsofjs;f4

fjdsfdksfkd5

dsfkjgds6

现在,我想在的前面一行,也就是 dsfkjgds6 和之间添加一行文字,文字

如下

请问应该如何写?

------解决方案--------------------

Assembly code

[root@RHEL6A tmp]# cat

123224rsiskd1

sdfkldsfjkslf2

fdsjlfjlsdf3

fdjsofjs;f4

fjdsfdksfkd5

dsfkjgds6

[root@RHEL6A tmp]# awk '{if ($0=="") printf("%sn

="d.e"/>n",$0);else print $0}'

123224rsiskd1

sdfkldsfjkslf2

fdsjlfjlsdf3

fdjsofjs;f4

fjdsfdksfkd5

dsfkjgds6

[root@RHEL6A tmp]#

【例4】

如何方便的使用shell脚本来解析xml文件

最近在项目中,需要用到shell脚本来解析xml文件。在网上搜了一下,发现有xmlsh等可

以用,但是都需要下载安装,使用比较麻烦,后来经过查找在stackoverflow上找到了解决

方法,将脚本记录如下。

项目中的主要需求为: 在xml文件中,需要配置连接的服务器的IP和端口号等信息,

供游戏逻辑程序作为服务的客户端进行解析使用。但同时,这些IP和端口号也是在进行服

务器部署时需要配置的,因而这份配置在两个地方需要用到。

一开始考虑到服务器部署脚本中解析文本方便一些,因而同一份配置编写了2份。但后

来考虑到后续部署的方便和较少人工配置出错的可能性,因而想到直接在部署脚本中使用

xml文件来配置服务器的IP和端口号相关信息。具体脚本如下:

[html] view plaincopy

1. #!/bin/sh

2.

3. Usage()

4. {

5. echo "Usage: ./install_ "

6. exit 1

7. }

8.

9. if [ $# -ne 1 ]

10. then

11. Usage

12. fi

13.

14. if [ ! -e "$1" ]

15. then

16. echo "fail to load data from file, file $1 not exist!"

17. exit 1

18. fi

19.

20. attrget()

21. {

22. ATTR_PAIR=${1#*$2="}

23. echo "${ATTR_PAIR%%"*}"

24. }

25.

26. install_all_svrs()

27. {

28. if [ $# -ne 1 ]

29. then

30. echo "Invalid call of function install_all_svrs, no input fi

le!"

31. exit 1

32. fi

33.

34. local IFS=>

35.

36. while read -d < ENTITY CONTENT

37. do

38. TAG_NAME=${ENTITY%% *}

39. ATTRIBUTES=${ENTITY#* }

40.

41. if [[ $TAG_NAME == "group" ]]

42. then

43. GROUP=`attrget ${ATTRIBUTES} "id"`

44. HOST=`attrget ${ATTRIBUTES} "host"`

45. PORT=`attrget ${ATTRIBUTES} "port"`

46. HTTPPORT=`attrget ${ATTRIBUTES} "httpport"`

47.

48. echo "./ $GROUP $HOST $PORT $HTTPPORT"

49. ./ $GROUP $HOST $PORT $HTTPPORT

50. fi

51. done < $1

52. }

53.

54. install_all_svrs $1

55.

56. #while read -d

57. #do

58. # var=`echo ${line} | awk '$1 ~/^[0-9]+$/ {print $1}'`

59. # if [ -z ${var} ]

60. # then

61. # continue;

62. # fi

63.

64. # ./ $line

65.

66. #done < $1

其中,xml文件的解析代码主要在install_all_svrs函数中。具体原理主要还是利用shell

的字符串处理技巧,下面主要分析几个主要的技巧:

${StrName%%TAG*} 表示截取字符串从左向右的第一个TAG之前的字符串;

${StrName#*TAG} 表示截取字符串从左向右的第一个TAG分割的之后的字符串,包含

TAG;

${StrName%%TAG} 表示截取字符串从左向右的第一个TAG分割之前的字符串,不包

含TAG;

【例5】请问如何利用shell脚本读取配置文件(.xml文件)中的信息

.xml文件内容类似如下:

[html]

1

192.168.1.100

2

192.168.1.200

[/html]

请问如何在shell脚本中读取指定的信息赋给一个变量?

比如在脚本中读取这个文件,获取ID为2的主机的IP给变量HOSTIP?

谢谢!

是想弄一个通用的方法,自己用c写个接口,下面是用sed,grep,awk处理你这个问题的,

不具有一般性

Shell代码

1. sed -e :a -e 'N;s/n//;ta;' | grep -o "2.*" | awk -F "[<>]" '{p

rint $7}'

【例6】

利用

源文件

---------------------

shell脚本文本过滤XML文件-awk工具

格式化输出文件

ID: 123 artist: linkin park title In the end

ID: 456 artist: arvil title thing's you never know

---------------------

文本过滤的shell脚本(写的很实用)

#!/bin/bash

XML_FILE_NAME=$1

grep "lrc" ${XML_FILE_NAME} | cut -d '"' -f 2,4,6 | awk 'BEGIN {FS="""}

{id[NR]=$1;artist[NR]=$2;title[NR]=$3}END {for (i=1;i

id[i]"tartist: " artist[i]"ttitle" title[i]}'

【例7】

举个例子:

一个xml文件内容是:

"/DTDs/">

Executable

test

Delete

delete

怎么实现删除Executable

test

添加 Add

add

到第七行?

PLIST 1.0//EN"

回复 #1 deronjazz 的帖子

sed -e '7itAddntadd' -e '/Executable/{N;d}'

【例8】shell处理xml,节点丢失

近来需要使用shell来处理XML文件。

1. 通过shell脚本解析XML,获取节点名称和节点值

2. 通过shell脚本动态生成XML。

拿到XXX部门发来得XML文件模板:

111

1

20

29

10086

1355004

]]>

XML文件中节点说明:

DataType 必须且只能填1项

ConsistencyType 必须且只能填1项

ValidTimeStart 可以没有

ValidTimeEnd 必须且只能填1项

UserRange 可以没有,也可以有多项

SPRange 可以没有,也可以有多项

Shell脚本 :

#! /bin/sh -

cat "$1" |

sed -e 's#systemitem *role="url"#URL#g' -e 's#/systemitem#URL#' |

tr ' (){}[]' 'nnnnnnn' |

egrep '>[^<>]+

awk -F'[<>]' -v FILE="$1"

'{ print($2, $3) }'

# sh

DataType 111

ConsistencyType 1

ValidTimeStart 20

ValidTimeEnd 29

UserRange 10086

UserRange 1355004

通过执行Shell可以得出如上结果,但跟我的需求结果有些差异,我预想输出的应该是:

DataType 111

ConsistencyType 1

ValidTimeStart 20

ValidTimeEnd 29

UserRange 10086

UserRange 1355004

UserRange <- 这个UserRange 因为节点没有值,这里应该是空值

SPRange <- 这个SPRange 因为节点没有值,这里应该是空值

-------------------------------------------------------

请各位帮忙修改我的shell以达到我的预想输出结果。谢谢!

回答:

方案一:

近来需要使用shell来处理XML文件。

1. 通过shell脚本解析XML,获取节点名称和节点值

2. 通过shell脚本动态生成XML。

拿到XXX部门发来得XML文件模板:

111

1

20

29

10086

1355004

]]>

XML文件中节点说明:

DataType 必须且只能填1项

ConsistencyType 必须且只能填1项

ValidTimeStart 可以没有

ValidTimeEnd 必须且只能填1项

UserRange 可以没有,也可以有多项

SPRange 可以没有,也可以有多项

Shell脚本 :

#! /bin/sh -

cat "$1" |

sed -e 's#systemitem *role="url"#URL#g' -e 's#/systemitem#URL#' |

tr ' (){}[]' 'nnnnnnn' |

egrep '>[^<>]+

awk -F'[<>]' -v FILE="$1"

'{ print($2, $3) }'

# sh

DataType 111

ConsistencyType 1

ValidTimeStart 20

ValidTimeEnd 29

UserRange 10086

UserRange 1355004

通过执行Shell可以得出如上结果,但跟我的需求结果有些差异,我预想输出的应该是:

DataType 111

ConsistencyType 1

ValidTimeStart 20

ValidTimeEnd 29

UserRange 10086

UserRange 1355004

UserRange <- 这个UserRange 因为节点没有值,这里应该是空值

SPRange <- 这个SPRange 因为节点没有值,这里应该是空值

-------------------------------------------------------

请各位帮忙修改我的shell以达到我的预想输出结果。谢谢!

方案二:

问题已经解决,

感谢楽楽提供的awk单行脚本:

awk 'BEGIN{FS="[<>]"}NR>6 && NR<15{sub(/t+/,"",$1);print $2,$3}'

脚本说明:

NR>6 && NR<15 几行与几行 之间(虽然这里写的比较死板。但是不影响使用,可以考

虑自动匹配)

BEGIN{FS="[<>]"} 定义多分隔符

sub(/t+/,"",$1) 把 $1 的 多 t 替换为 一个 “”

再打印出 $2 $3

感谢小玉提供的sed单行脚本:

sed -n -r 's/^[t ]*<([^>]+)>([^<>]*)<1>/1=2/p'

脚本说明:

-n 只显示被特殊处理的行,同 /p 配合使用

-r 支持sed 延伸型正规表示法的语法

's/^[t ]*<([^>]+)>([^<>]*)<1>/1=2/p' 这段 s/ /p 之间没看懂。

本文标签: 文件脚本修改需要解析