Ответ 1
Вы можете извлечь его, включая токены с sed. Затем используйте головку и хвост, чтобы вырезать токены.
... | sed -n "/this is token 1/,/this is token 2/p" | head -n-1 | tail -n+2
У меня есть текстовый файл, который выглядит так:
random useless text
<!-- this is token 1 -->
para1
para2
para3
<!-- this is token 2 -->
random useless text again
Я хочу извлечь текст между токенами (исключая, конечно же, токены). Я попытался использовать ## и %% для извлечения данных между ними, но это не сработало. Я думаю, что это не предназначено для манипулирования такими большими текстовыми файлами. Любые предложения, как я могу это сделать? возможно awk или sed?
Вы можете извлечь его, включая токены с sed. Затем используйте головку и хвост, чтобы вырезать токены.
... | sed -n "/this is token 1/,/this is token 2/p" | head -n-1 | tail -n+2
Нет необходимости в 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" }
end ifВозможно, sed и awk имеют более элегантные решения, но у меня есть подход "бедных" с grep, cut, head и tail.
#!/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}
Для чего бы то ни было, я бы нашел для 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 '/<!-- this is token 1 -->/,/<!-- this is token 2 -->/p' your_input_file
| egrep -v '<!-- this is token . -->'
не нужно вызывать могущественный 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
С уважением
Realex