




已阅读5页,还剩23页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
12.4. 文本处理命令处理文本和文本文件的命令sort文件排序, 通常用在管道中当过滤器来使用. 这个命令可以依据指定的关键字或指定的字符位置, 对文件行进行排序. 使用-m选项, 它将会合并预排序的输入文件. 想了解这个命令的全部参数请参考这个命令的info页. 请参考例子 10-9,例子 10-10, 和例子 A-8.tsort拓扑排序, 读取以空格分隔的有序对, 并且依靠输入模式进行排序.uniq这个过滤器将会删除一个已排序文件中的重复行. 这个命令经常出现在sort命令的管道后边. 1cat list-1 list-2 list-3 | sort | uniq final.list 2# 将3个文件连接起来, 3# 将它们排序, 4# 删除其中重复的行, 5# 最后将结果重定向到一个文件中. -c用来统计每行出现的次数, 并把次数作为前缀放到输出行的前面.bash$ cat testfileThis line occurs only once. This line occurs twice. This line occurs twice. This line occurs three times. This line occurs three times. This line occurs three times.bash$ uniq -c testfile 1 This line occurs only once. 2 This line occurs twice. 3 This line occurs three times.bash$ sort testfile | uniq -c | sort -nr 3 This line occurs three times. 2 This line occurs twice. 1 This line occurs only once. sort INPUTFILE | uniq -c | sort -nr命令先对INPUTFILE文件进行排序, 然后统计每行出现的次数(sort命令的-nr选项会产生一个数字的反转排序). 这种命令模板一般都用来分析log文件或者用来分析字典列表, 或者用在那些需要检查文本词汇结构的地方.例子 12-11. 分析单词出现的频率 1#!/bin/bash 2# wf.sh: 分析文本文件中词汇出现的频率. 3# wf2.sh脚本是一个效率更高的版本. 4 5 6# 从命令行中检查输入的文件. 7ARGS=1 8E_BADARGS=65 9E_NOFILE=66 10 11if $# -ne $ARGS # 检验传递到脚本中参数的个数. 12then 13 echo Usage: basename $0 filename 14 exit $E_BADARGS 15fi 16 17if ! -f $1 # 检查传入的文件是否存在. 18then 19 echo File $1 does not exist. 20 exit $E_NOFILE 21fi 22 23 24 25# 26# main () 27sed -e s/./g -e s/,/g -e s/ / 28/g $1 | tr A-Z a-z | sort | uniq -c | sort -nr 29# = 30# 检查单词出现的频率 31 32# 过滤掉句号和逗号, 33#+ 并且把单词间的空格转化为换行, 34#+ 然后转化为小写, 35#+ 最后统计单词出现的频率并按频率排序. 36 37# Arun Giridhar建议将上边的代码修改为: 38# . . . | sort | uniq -c | sort +1 -f | sort +0 -nr 39# 这句添加了第2个排序主键, 所以 40#+ 这个与上边等价的例子将按照字母顺序进行排序. 41# 就像他所解释的: 42# 这是一个有效的根排序, 首先对频率最少的 43#+ 列进行排序 44#+ (单词或者字符串, 忽略大小写) 45#+ 然后对频率最高的列进行排序. 46# 47# 像Frank Wang所解释的那样, 上边的代码等价于: 48#+ . . . | sort | uniq -c | sort +0 -nr 49#+ 用下边这行也行: 50#+ . . . | sort | uniq -c | sort -k1nr -k 51# 52 53exit 0 54 55# 练习: 56# - 57# 1) 使用sed命令来过滤其他的标点符号, 58#+ 比如分号. 59# 2) 修改这个脚本, 添加能够过滤多个空格或者 60# 空白的能力. bash$ cat testfileThis line occurs only once. This line occurs twice. This line occurs twice. This line occurs three times. This line occurs three times. This line occurs three times.bash$ ./wf.sh testfile 6 this 6 occurs 6 line 3 times 3 three 2 twice 1 only 1 once expand,unexpandexpand命令将会把每个tab转化为一个空格. 这个命令经常用在管道中.unexpand命令将会把每个空格转化为一个tab. 效果与expand命令相反.cut一个从文件中提取特定域的工具. 这个命令与awk中使用的print $N命令很相似, 但是更受限. 在脚本中使用cut命令会比使用awk命令来得容易一些. 最重要的选项就是-d(字段定界符)和-f(域分隔符)选项.使用cut来获得所有mount上的文件系统的列表: 1cut -d -f1,2 /etc/mtab使用cut命令列出OS和内核版本: 1uname -a | cut -d -f1,3,11,12使用cut命令从e-mail中提取消息头:bash$ grep Subject: read-messages | cut -c10-80Re: Linux suitable for mission-critical apps? MAKE MILLIONS WORKING AT HOME! Spam complaint Re: Spam complaint使用cut命令来分析一个文件: 1# 列出所有在/etc/passwd中的用户. 2 3FILENAME=/etc/passwd 4 5for user in $(cut -d: -f1 $FILENAME) 6do 7 echo $user 8done 9 10# 感谢Oleg Philon对此的建议. cut -d -f2,3 filename等价于awk -F print $2, $3 filename你甚至可以指定换行符作为字段定界符. 这个小伎俩实际上就是在命令行上插入一个换行(RETURN). (译者: linux使用lf作为换行符).bash$ cut -d -f3,7,19 testfileThis is line 3 of testfile. This is line 7 of testfile. This is line 19 of testfile. 感谢, Jaka Kranjc指出这点.请参考例子 12-43.paste将多个文件, 以每个文件一列的形式合并到一个文件中, 合并后文件中的每一列就是原来的一个文件. 与cut结合使用, 经常用于创建系统log文件.join这个命令与paste命令属于同类命令. 但是它能够完成某些特殊的目地. 这个强力工具能够以一种特殊的形式来合并两个文件, 这种特殊的形式本质上就是一个关联数据库的简单版本.join命令只能够操作两个文件. 它可以将那些具有特定标记域(通常是一个数字标签)的行合并起来, 并且将结果输出到stdout. 被加入的文件应该事先根据标记域进行排序以便于能够正确的匹配. 1File: 1.data 2 3100 Shoes 4200 Laces 5300 Socks 1File: 2.data 2 3100 $40.00 4200 $1.00 5300 $2.00bash$ join 1.data 2.dataFile: 1.data 2.data 100 Shoes $40.00 200 Laces $1.00 300 Socks $2.00 在输出中标记域将只会出现一次.head把文件的头部内容打印到stdout上(默认为10行, 可以自己修改). 这个命令有一些比较有趣的选项.例子 12-12. 哪个文件是脚本? 1#!/bin/bash 2# script-detector.sh: 在一个目录中检查所有的脚本文件. 3 4TESTCHARS=2 # 测试前两个字符. 5SHABANG=#! # 脚本都是以#!开头的. 6 7for file in * # 遍历当前目录下的所有文件. 8do 9 if head -c$TESTCHARS $file = $SHABANG 10 # head -c2 #! 11 # -c 选项将从文件头输出指定个数的字符, 12 #+ 而不是默认的行数. 13 then 14 echo File $file is a script. 15 else 16 echo File $file is *not* a script. 17 fi 18done 19 20exit 0 21 22# 练习: 23# - 24# 1) 修改这个脚本, 25#+ 让它可以指定扫描的路径. 26#+ (而不是只搜索当前目录). 27# 28# 2) 以这个脚本目前的状况, 它不能正确识别出 29#+ Perl, awk, 和其他一些脚本语言的脚本文件. 30# 修正这个问题.例子 12-13. 产生10-进制随机数 1#!/bin/bash 2# rnd.sh: 输出一个10进制随机数 3 4# 由Stephane Chazelas所编写的这个脚本. 5 6head -c4 /dev/urandom | od -N4 -tu4 | sed -ne 1s/.* /p 7 8 9# = # 10 11# 分析 12# - 13 14# head: 15# -c4 选项将取得前4个字节. 16 17# od: 18# -N4 选项将限制输出为4个字节. 19# -tu4 选项将使用无符号10进制格式来输出. 20 21# sed: 22# -n 选项, 使用s命令与p标志组合的方式, 23# 将会只输出匹配的行. 24 25 26 27# 本脚本作者解释sed命令的行为如下. 28 29# head -c4 /dev/urandom | od -N4 -tu4 | sed -ne 1s/.* /p 30# - | 31 32# 假设一直处理到sed命令时的输出- | 33# 为 0000000 1198195154n 34 35# sed命令开始读取字串: 0000000 1198195154n. 36# 这里它发现一个换行符, 37#+ 所以sed准备处理第一行 (0000000 1198195154). 38# sed命令开始匹配它的和. 第一个匹配的并且只有这一个匹配的: 39 40# range action 41# 1 s/.* /p 42 43# 因为行号在range中, 所以sed开始执行action: 44#+ 替换掉以空格结束的最长的字符串, 在这行中这个字符串是 45# (0000000 ), 用空字符串(/)将这个匹配到的字串替换掉, 如果成功, 那就打印出结果 46# (p在这里是s命令的标志, 这与单独的p命令是不同的). 47 48# sed命令现在开始继续读取输入. (注意在继续之前, 49#+ continuing, 如果没使用-n选项的话, sed命令将再次 50#+ 将这行打印一遍). 51 52# 现在, sed命令读取剩余的字符串, 并且找到文件的结尾. 53# sed命令开始处理第2行(这行也被标记为$ 54# 因为这已经是最后一行). 55# 所以这行没被匹配到中, 这样sed命令就结束了. 56 57# 这个sed命令的简短的解释是: 58# 在第一行中删除第一个空格左边全部的字符, 59#+ 然后打印出来. 60 61# 一个更好的来达到这个目的的方法是: 62# sed -e s/.* /;q 63 64# 这里, 和分别是(也可以写成 65# sed -e s/.* / -e q): 66 67# range action 68# nothing (matches line) s/.* / 69# nothing (matches line) q (quit) 70 71# 这里, sed命令只会读取第一行的输入. 72# 将会执行2个命令, 并且会在退出之前打印出(已经替换过的)这行(因为q action), 73#+ 因为没使用-n选项. 74 75# = # 76 77# 也可以使用如下一个更简单的语句来代替: 78# head -c4 /dev/urandom| od -An -tu4 79 80exit 0请参考例子 12-35.tail将一个文件结尾部分的内容输出到stdout中(默认为10行). 通常用来跟踪一个系统logfile的修改情况, 如果使用-f选项的话, 这个命令将会继续显示添加到文件中的行.例子 12-14. 使用tail命令来监控系统log 1#!/bin/bash 2 3filename=sys.log 4 5cat /dev/null $filename; echo Creating / cleaning out file. 6# 如果文件不存在的话就创建文件, 7#+ 然后将这个文件清空. 8# : filename 和 filename 也能完成这个工作. 9 10tail /var/log/messages $filename 11# /var/log/messages 必须具有全局的可读权限才行. 12 13echo $filename contains tail end of system log. 14 15exit 0为了列出一个文本文件中的指定行的内容, 可以将head命令的输出通过管道传递到tail -1中. 比如head -8 database.txt | tail -1将会列出database.txt文件第8行的内容.下边是将一个文本文件中指定范围的所有行都保存到一个变量中: 1var=$(head -$m $filename | tail -$n) 2 3# filename = 文件名 4# m = 从文件开头到块结尾的行数 5# n = 想保存到变量中的指定行数(从块结尾开始截断)请参考例子 12-5,例子 12-35和例子 29-6.grep使用正则表达式的一个多用途文本搜索工具. 这个命令本来是ed行编辑器中的一个命令/过滤器:g/re/p-global - regular expression - print.greppatternfile.在文件中搜索所有pattern出现的位置,pattern既可以是要搜索的字符串, 也可以是一个正则表达式.bash$ grep rstystem.$ osinfo.txtThe GPL governs the distribution of the Linux operating system. 如果没有指定文件参数,grep通常用在管道中对stdout进行过滤.bash$ ps ax | grep clock765 tty1 S 0:00 xclock 901 pts/1 S 0:00 grep clock -i选项在搜索时忽略大小写.-w选项用来匹配整个单词.-l选项仅列出符合匹配的文件, 而不列出匹配行.-r(递归) 选项不仅在当前工作目录下搜索匹配, 而且搜索子目录.-n选项列出所有匹配行, 并显示行号.bash$ grep -n Linux osinfo.txt2:This is a file containing information about Linux. 6:The GPL governs the distribution of the Linux operating system. -v(或者-invert-match)选项将会显示所有不匹配的行. 1grep pattern1 *.txt | grep -v pattern2 2 3# 匹配在*.txt中所有包含 pattern1的行, 4# 而*不显示*匹配包含pattern2的行. -c(-count) 选项将只会显示匹配到的行数的总数,而不会列出具体的匹配. 1grep -c txt *.sgml # (在 *.sgml 文件中, 匹配txt的行数的总数.) 2 3 4# grep -cz . 5# 点 6# 意思是计数 (-c) 所有以空字符分割(-z) 的匹配 .的项 7# .是正则表达式的一个符号, 表达匹配任意一个非空字符(至少要包含一个字符). 8# 9printf a bnc dnnnnn000n000e000000nf | grep -cz . # 3 10printf a bnc dnnnnn000n000e000000nf | grep -cz $ # 5 11printf a bnc dnnnnn000n000e000000nf | grep -cz # 5 12# 13printf a bnc dnnnnn000n000e000000nf | grep -c $ # 9 14# 默认情况下, 是使用换行符(n)来分隔匹配项. 15 16# 注意 -z 选项是 GNU grep 特定的选项. 17 18 19# 感谢, S.C.当有多个文件参数的时候,grep将会指出哪个文件中包含具体的匹配.bash$ grep Linux osinfo.txt misc.txtosinfo.txt:This is a file containing information about Linux. osinfo.txt:The GPL governs the distribution of the Linux operating system. misc.txt:The Linux operating system is steadily gaining in popularity. 如果在grep命令只搜索一个文件的时候, 那么可以简单的把/dev/null作为第二个文件参数传递给grep.bash$ grep Linux osinfo.txt /dev/nullosinfo.txt:This is a file containing information about Linux. osinfo.txt:The GPL governs the distribution of the Linux operating system. 如果存在一个成功的匹配, 那么grep命令将会返回0作为退出状态码, 这样就可以将grep命令的结果放在脚本的条件测试中来使用, 尤其和-q(禁止输出)选项组合时特别有用. 1SUCCESS=0 # 如果grep匹配成功 2word=Linux 3filename=data.file 4 5grep -q $word $filename # -q选项将使得什么都不输出到stdout上. 6 7if $? -eq $SUCCESS 8# if grep -q $word $filename 这句话可以代替行 5 - 7. 9then 10 echo $word found in $filename 11else 12 echo $word not found in $filename 13fi例子 29-6展示了如何使用grep命令在一个系统logfile中进行一个单词的模式匹配.例子 12-15. 在脚本中模拟grep的行为 1#!/bin/bash 2# grp.sh: 一个非常粗糙的grep命令的实现. 3 4E_BADARGS=65 5 6if -z $1 # 检查传递给脚本的参数. 7then 8 echo Usage: basename $0 pattern 9 exit $E_BADARGS 10fi 11 12echo 13 14for file in * # 遍历$PWD下的所有文件. 15do 16 output=$(sed -n /$1/p $file) # 命令替换. 17 18 if ! -z $output # 如果$output不加双引号将会发生什么? 19 then 20 echo -n $file: 21 echo $output 22 fi # sed -ne /$1/s|$file: |p 这句与上边这段等价. 23 24 echo 25done 26 27echo 28 29exit 0 30 31# 练习: 32# - 33# 1) 在任何给定的文件中,如果有超过一个匹配的话, 在输出中添加新行. 34# 2) 添加一些特征. 如何使用grep命令来搜索两个(或两个以上)独立的模式? 如果你想在一个或多个文件中显示既匹配pattern1又匹配pattern2的所有匹配的话, 那又该如何做呢? (译者: 这是取交集的情况, 如果取并集该怎么办呢?)一个方法是通过管道来将grep pattern1的结果传递到grep pattern2中.比如, 给定如下文件: 1# 文件名: tstfile 2 3This is a sample file. 4This is an ordinary text file. 5This file does not contain any unusual text. 6This file is not unusual. 7Here is some text.现在, 让我们在这个文件中搜索既包含file又包含text的所有行.bash$ grep file tstfile# 文件名: tstfile This is a sample file. This is an ordinary text file. This file does not contain any unusual text. This file is not unusual.bash$ grep file tstfile | grep textThis is an ordinary text file. This file does not contain any unusual text.-egrep-扩展的grep- 这个命令与grep -E等价. 这个命令用起来有些不同, 由于使用正则表达式的扩展集合, 将会使得搜索更具灵活性. 它也允许逻辑|(或)操作.bash $ egrep matches|Matches file.txtLine 1 matches. Line 3 Matches. Line 4 contains matches, but also Matches fgrep-快速的grep- 这个命令与grep -F等价. 这是一种按照字符串字面意思进行的搜索(即不允许使用正则表达式), 这样有时候会使搜索变得容易一些.在某些Linux发行版中,egrep和fgrep都是grep命令的符号链接或者别名, 只不过在调用的时候分别使用了-E和-F选项罢了.例子 12-16. 在1913年的韦氏词典中查找定义 1#!/bin/bash 2# dict-lookup.sh 3 4# 这个脚本在1913年的韦氏词典中查找定义. 5# 这本公共词典可以通过不同的 6#+ 站点来下载,包括 7#+ Project Gutenberg (/etext/247). 8# 9# 在使用本脚本之前, 10#+ 先要将这本字典由DOS格式转换为UNIX格式(只以LF作为行结束符). 11# 将这个文件存储为纯文本形式, 并且保证是未压缩的ASCII格式. 12# 将DEFAULT_DICTFILE变量以path/filename形式设置好. 13 14 15E_BADARGS=65 16MAXCONTEXTLINES=50 # 显示的最大行数. 17DEFAULT_DICTFILE=/usr/share/dict/webster1913-dict.txt 18 # 默认的路径和文件名. 19 # 在必要的时候可以进行修改. 20# 注意: 21# - 22# 这个特定的1913年版的韦氏词典 23#+ 在每个入口都是以大写字母开头的 24#+ (剩余的字符都是小写). 25# 只有每部分的第一行是以这种形式开始的, 26#+ 这也就是为什么搜索算法是下边的这个样子. 27 28 29 30if -z $(echo $1 | sed -n /A-Z/p) 31# 必须指定一个要查找的单词, 32#+ 并且这个单词必须以大写字母开头. 33then 34 echo Usage: basename $0 Word-to-define dictionary-file 35 echo 36 echo Note: Word to look up must start with capital letter, 37 echo with the rest of the word in lowercase. 38 echo - 39 echo Examples: Abandon, Dictionary, Marking, etc. 40 exit $E_BADARGS 41fi 42 43 44if -z $2 # 也可以指定不同的词典 45 #+ 作为这个脚本的第2个参数传递进来. 46then 47 dictfile=$DEFAULT_DICTFILE 48else 49 dictfile=$2 50fi 51 52# - 53Definition=$(fgrep -A $MAXCONTEXTLINES $1 $dictfile) 54# 以 Word . 这种形式定义 55# 56# 当然, 即使搜索一个特别大的文本文件的时候 57#+ fgrep也是足够快的. 58 59 60# 现在, 剪掉定义块. 61 62echo $Definition | 63sed -n 1,/A-Z/p | 64# 从输出的第一行 65#+ 打印到下一部分的第一行. 66sed $d | sed $d 67# 删除输出的最后两行 68#+ (空行和下一部分的第一行). 69# - 70 71exit 0 72 73# 练习: 74# - 75# 1) 修改这个脚本, 让它具备能够处理任何字符形式的输入 76# + (大写, 小写, 或大小写混合), 然后将其转换为 77# + 能够处理的统一形式. 78# 79# 2) 将这个脚本转化为一个GUI应用, 80# + 使用一些比如像gdialog的东西 . . . 81# 这样的话, 脚本将不再从命令行中 82# + 取得这些参数. 83# 84# 3) 修改这个脚本让它具备能够分析另外一个 85# + 公共词典的能力, 比如 U.S. Census Bureau Gazetteer.agrep(近似grep)扩展了grep近似匹配的能力. 搜索的字符串可能会与最终匹配结果所找到字符串有些不同. 这个工具并不是核心Linux发行版的一部分.为了搜索压缩文件, 应使用zgrep,zegrep, 或zfgrep. 这些命令也可以对未压缩的文件进行搜索, 只不过会比一般的grep,egrep, 和fgrep慢上一些. 当然, 在你要搜索的文件中如果混合了压缩和未压缩的文件的话, 那么使用这些命令是非常方便的.如果要搜索bzipped类型的文件, 使用bzgrep.looklook命令与grep命令很相似, 但是这个命令只能做字典查询, 也就是它所搜索的文件必须是已经排过序的单词列表. 默认情况下, 如果没有指定搜索哪个文件,look命令就默认搜索/usr/dict/words(译者: 感觉好像应该是/usr/share/dict/words), 当然也可以指定其他目录下的文件进行搜索.例子 12-17. 检查列表中单词的正确性 1#!/bin/bash 2# lookup: 对指定数据文件中的每个单词都做一遍字典查询. 3 4file=words.data # 指定的要搜索的数据文件. 5 6echo 7 8while $word != end # 数据文件中最后一个单词. 9do 10 read word # 从数据文件中读, 因为在循环的后边重定向了. 11 look $word /dev/null # 不想将字典文件中的行显示出来. 12 lookup=$? # look命令的退出状态. 13 14 if $lookup -eq 0 15 then 16 echo $word is valid. 17 else 18 echo $word is invalid. 19 fi 20 21done /dev/null 35 then echo $word is valid. 36 else echo $word is invalid. 37 fi 38done $file 39 40exit 0sed,awk这个两个命令都是独立的脚本语言, 尤其适合分析文本文件和命令输出. 既可以单独使用, 也可以结合管道和在shell脚本中使用.sed非交互式的流编辑器, 在批处理模式下, 允许使用多个ex命令. 你会发现它在shell脚本中非常有用.awk可编程的文件提取器和文件格式化工具, 在结构化的文本文件中, 处理或提取特定域(特定列)具有非常好的表现. 它的语法与C语言很类似.wcwc可以统计文件或I/O流中的单词数量:bash $ wc /usr/share/doc/sed-4.1.2/README13 70 447 README13 lines 70 words 447 characterswc -w统计单词数量.wc -l统计行数量.wc -c统计字节数量.wc -m统计字符数量.wc -L给出文件中最长行的长度.使用wc命令来统计当前工作目录下有多少个.t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 梦幻花园的实现方法
- 2025浙江省金华成泰农商银行社会招聘考试含答案
- 2025浙江金华市武义县司法局招聘4人笔试备考试题及答案解析
- 2025云南楚雄州禄丰市教育体育局机关直属事业单位选调工作人员10人笔试含答案
- 初高中学生如何正确处理学校暴力问题
- 船舶货物运输事故调查规定
- 如何引导初高中学生正确应对生活挑战
- 2025四川内江市法院系统招聘聘用制审判辅助人员120人考试含答案
- 2025年事业单位工勤技能-广东-广东计算机操作员一级(高级技师)历年参考题库含答案解析
- 2025年四川宜宾兴文县第一次考调事业单位工作人员17人笔试备考题库及参考答案详解
- 防呆培训课件
- BSL实验室生物安全管理体系文件
- 帕金森综合症
- 幼儿园一校一档整改报告
- 高级综合英语知到智慧树章节测试课后答案2024年秋浙江中医药大学
- 家政员保洁流程
- 燃气锅炉招投标文件范本含安装
- 智能计算系统:从深度学习到大模型 第2版课件 8、第八章-智能编程语言
- 《我设计的机器人》课件
- 2024-2030年中国特征尺寸测量用扫描电子显微镜(CDSEM)行业发展策略与前景规划分析报告
- 2024年广西公需科目参考答案
评论
0/150
提交评论