tcl命令在linux中搜索txt文件中的特定单词

时间:2015-05-06 12:19:53

标签: linux tcl

我需要编写一个tcl脚本来处理文本文件的行。该文件看起来像

10.77.33.247    10.77.33.241        rtp 0x26
10.77.33.247    10.77.33.241        rtp 0x26
10.77.33.247    10.77.33.241        rtp 0x26
10.77.33.247    10.77.33.241            0x24
10.77.33.247    10.77.33.241            0x22
10.77.33.247    10.77.33.241            0x21

我需要能够遍历文件,并且对于包含rtp的每一行,在变量中存储其后面的值(例如,上面示例中的0x26)才能使用在剧本的其他部分。

5 个答案:

答案 0 :(得分:3)

这是一种(相当低级别的)Tcl方式。

set ch [open myfile.txt]
set data [chan read $ch]
chan close $ch

set lines [split [string trim $data] \n]

set res {}
foreach line $lines {
    if {[llength $line] > 3 && [lindex $line 2] eq {rtp}} {
        lappend res [lindex $line 3]
    }
}

如果将“myfile.txt”替换为数据文件的名称并运行此代码,则会在变量res中获得您收集的单词。

解释

通常最好在glenn jackman的答案中使用标准(内置或tcllib)命令,例如fileutil::foreachLine。但是,如果一个人想要一步一步地做,Tcl仍然很容易。

第一步是将文件内容放入内存。这也有一个标准命令:fileutil::cat,但以下序列将执行:

set ch [open myfile.txt]
set data [chan read $ch]
chan close $ch

(这或多或少等同于set data [fileutil::cat myfile.txt]。)

下一步是将文本拆分为行。修剪文本两端的空格总是一个好主意,否则松散的换行符会产生干扰处理的空元素。

set lines [split [string trim $data] \n]

在某些情况下,我们可能不得不将这些行拆分为字段列表,但是从示例中可以看出这些行已经可以用作列表(只有空格,字母数字和行为符合标点的行如点通常是)。

我们需要对匹配线进行测试。有几种替代方案适合您提供的示例数据,包括

string match *rtp* $line  ;# match every line that has "rtp" somewhere
[llength $line] > 3       ;# match every line that has more than three columns
[lindex $line 2] eq {rtp} ;# match every line where the third element is "rtp"

我们还需要一种方法来提取我们想要的数据。如果“rtp”之后的单词始终位于最后一列,[lindex $line end]将完成此任务。如果该单词始终位于第四列,但可能还有其他列,则[lindex $line 3]更好。

抓住其中几个替代方案,可以编写获得指定单词列表的程序

set res {}
foreach line $lines {
    if {[llength $line] > 3 && [lindex $line 2] eq {rtp}} {
        lappend res [lindex $line 3]
    }
}

(在伪代码中:获取一个空列表(res);测试每一行(使用上面两个测试的组合),从每个匹配行中提取所追求的单词并将其添加到res列表。)

或使用lmap(Tcl 8.6 +)

set res [lmap line $lines {
    if {[llength $line] > 3 && [lindex $line 2] eq {rtp}} {
        lindex $line 3
    } else {
        continue
    }
}]

“rtp”字后面的所有单词现在应该在res中。如果你只是想要最后一场比赛,那就是[lindex $res end]

文档:chancontinueforeachiflappendlindexllength,{{3 }},lmapopensetsplit

答案 1 :(得分:0)

假设您的文件是foo.txt:

grep "word" foo.txt

答案 2 :(得分:0)

grep" 0x26" file.txt的 将显示其中包含0x26的所有行。

答案 3 :(得分:0)

tcllib有很多优点:

% package require fileutil
1.14.5
% fileutil::foreachLine line "file" {
    if {[string match {*rtp*} $line]} {
        lappend values [lindex [split $line] end]
    }
}
% puts $values
0x26 0x26 0x26

答案 4 :(得分:0)

以下代码适用于从文件夹中获取文本(""):



proc aifWebcamInitVideo {} {	
	
	variable devicePath "c:/testfile.txt"

	#ffmpeg command to get the device name connected to system
	exec ffmpeg -list_devices true -f dshow -i dummy >& $devicePath &
	
	after 4000                                                                                                   ;# wait of 4 seconds so that device can be selected.
	set files [glob $aif::LogRootDir/*]                                                                          ;# Look for all the files.
	foreach file $files {
	set fileName $devicePath
		if {[string match $fileName $file ] } {                                                                  ;# this if statement check currently captured video with the files present in directory.
			set file [open $devicePath ]                                                                         ;# open the file
			set file_device [read  $file]
			set data [split $file_device "\n"]                                                                   ;# divides the open file into lines.
			foreach line $data {                                                      
				if {[regexp {"([^""]*)"} $line -> substring]} {                                                  ;# check for the quotes to retrieve the device connected to system.
					set result $substring
					lappend cameraList $result                                                                   ;# makes the list of devices.
					set camera [lindex $cameraList 0]
				}
			}
			close $file
			break
		} 
	}
	
	#values passed to FFMPEG command.
	
	variable TableCamera $camera
	puts "Device selected for Video capture is : $TableCamera"                                     ;# gets the first device from the list
}