我有一个文本文件,其内容如下:
random useless text
<!-- this is token 1 -->
para1
para2
para3
<!-- this is token 2 -->
random useless text again
我想提取标记之间的文本(不包括标记本身)。我尝试使用##和%%来提取标记之间的数据,但它没有起作用。我认为这并不适用于操作如此大的文本文件。有什么建议吗?也许可以使用awk或sed?
我有一个文本文件,其内容如下:
random useless text
<!-- this is token 1 -->
para1
para2
para3
<!-- this is token 2 -->
random useless text again
我想提取标记之间的文本(不包括标记本身)。我尝试使用##和%%来提取标记之间的数据,但它没有起作用。我认为这并不适用于操作如此大的文本文件。有什么建议吗?也许可以使用awk或sed?
不需要使用head
和tail
或grep
,也不需要多次读取文件:
sed -n '/<!-- this is token 1 -->/{:a;n;/<!-- this is token 2 -->/b;p;ba}' inputfile
解释:
-n
- 不进行隐式打印/<!-- this is token 1 -->/{
- 如果找到起始标记,则
:a
- 标签“a”
n
- 读取下一行/<!-- this is token 2 -->/q
- 如果是结束标记,则退出p
- 否则,打印该行ba
- 跳转到标签“a”}
结束判断您可以使用sed提取它,包括令牌。 然后使用head和tail剥离令牌。
... | sed -n "/这是令牌1/,/这是令牌2/p" | head -n-1 | tail -n+2
head: illegal line count -- -1
的错误提示。 - balupton请尝试以下方法:
sed -n '/<!-- this is token 1 -->/,/<!-- this is token 2 -->/p' your_input_file
| egrep -v '<!-- this is token . -->'
#!/bin/bash
dataFile="/path/to/some/data.txt"
startToken="token 1"
stopToken="token 2"
startTokenLine=$( grep -n "${startToken}" "${dataFile}" | cut -f 1 -d':' )
stopTokenLine=$( grep -n "${stopToken}" "${dataFile}" | cut -f 1 -d':' )
let stopTokenLine=stopTokenLine-1
let tailLines=stopTokenLine-startTokenLine
head -n ${stopTokenLine} ${dataFile} | tail -n ${tailLines}
不需要调用强大的sed / awk / perl。您可以仅使用"bash"来完成:
#!/bin/bash
STARTFLAG="false"
while read LINE; do
if [ "$STARTFLAG" == "true" ]; then
if [ "$LINE" == '<!-- this is token 2 -->' ];then
exit
else
echo "$LINE"
fi
elif [ "$LINE" == '<!-- this is token 1 -->' ]; then
STARTFLAG="true"
continue
fi
done < t.txt
对于这样的事情,我会选择Perl,因为它具有(除其他外)sed
和awk
的功能。类似以下代码(注意-未经测试):
my $recording = 0;
my @results = ();
while (<STDIN>) {
chomp;
if (/token 1/) {
$recording = 1;
}
else if (/token 2/) {
$recording = 0;
}
else if ($recording) {
push @results, $_;
}
}
sed -n "/TOKEN1/,/TOKEN2/p" <YOUR INPUT FILE> | sed -e '/TOKEN1/d' -e '/TOKEN2/d'
sed -n '/^----$/{n;/^----$/q;p;}' /dev/null
可以正常工作(没有输出),但是添加循环(即sed -n '/^----$/{:a;n;/^----$/q;p;ba}' /dev/null
)会导致sed出现unexpected EOF (pending }'s)
错误。我必须将使用循环的版本拆分成多行来编写。 :-( - Frerich Raabe<!-- this is token 2 -->
? - Iliased
命令中可能会很棘手,因为您需要使用双引号才能对变量进行评估。您可能需要通过转义某些字符来避免意外的评估。您还应该在变量名称中使用花括号,以将其与其他可能被视为名称一部分的字符分开。在这种特殊情况下:var='<!-- this is token 2 -->'; sed -n "/<!-- this is token 1 -->/{:a;n;/${var}/b;p;ba}" inputfile
应该可以工作(未经测试)。 - Dennis Williamson/*
和*/
,它会出现错误sed: -e expression #1, char 3: unknown command: *'
。但如果我用\
转义它们,那么就会出现一堆其他错误,比如sed: -e expression #1, char 20: unknown command: u
、sh: p: command not found
和sh: ba}: command not found
。看起来它是按字面意思执行的。有什么想法吗? - Ilia