у меня есть файл movie.html:
<html>
<head><title>Index of /Data/Movies/Hollywood/2016_2017/</title></head>
<body bgcolor = "white">
<h1>Index of /Data/Movies/Hollywood/2016_2017/</h1><hr><pre><a href = "../">../</a>
<a href = "1%20Buck%20%282017%29/">1 Buck (2017)/</a> 25-Nov-2019 10:25 -
<a href = "1%20Mile%20to%20You%20%282017%29/">1 Mile to You (2017)/</a> 25-Nov-2019 10:26 -
<a href = "1%20Night%20%282016%29/">1 Night (2016)/</a> 25-Nov-2019 10:27 -
</pre><hr></body>
</html>
Я хочу получить несколько слов с разделителями:
title | link
1 Buck (2017) | 1%20Buck%20%282017%29/
1 Mile to You (2017) | 1%20Mile%20to%20You%20%282017%29/
1 Night (2016) | 1%20Night%20%282016%29/
Я пробовал этот код:
awk -F'[><]' 'BEGIN{ print "title","link" } /%29/ {print $3,$2}' movie.html > output.txt
но результат не такой, как я ожидал, пожалуйста, помогите мне, я все еще новичок





Анализировать html с помощью регулярного выражения не рекомендуется по нескольким причинам (см. https://stackoverflow.com/a/1732454/12957340), но вот одно из возможных решений:
awk -F'[<>/"]' 'BEGIN{ print "title | link" }; /\(.*\)/ {print $6 " | " $3}' movie.html
С вашими показанными образцами, не могли бы вы попробовать следующее. Я предпочитаю это с функцией match.
awk '
BEGIN{
OFS = " | "
print "title | link"
}
match($0,/^<a href = "[^"]*/){
val=substr($0,RSTART+9,RLENGTH-9)
match($0,/>.*</a>/)
print substr($0,RSTART+1,RLENGTH-6),val
}' Input_file
Объяснение: Добавление подробного объяснения вышеизложенного.
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section of this program from here.
OFS = " | " ##Setting OFS as space | space here.
print "title | link" ##Printing title space | space link here.
}
match($0,/^<a href = "[^"]*/){ ##Using match to match regex from starting of line <a href = " till " comes.
val=substr($0,RSTART+9,RLENGTH-9) ##Creating val which has sub string of matched above text, making it as per OP needs here.
match($0,/>.*</a>/) ##Using match to match from > till </a> here.
print substr($0,RSTART+1,RLENGTH-6),val ##Printing current matched sub string(by above match function) and val value here.
}
' Input_file ##Mentioning Input_file name here.
Другой способ, я думаю, вы могли бы получить обработанные строки с помощью grep, а затем использовать формат awk для вывода содержимого.
grep -oP 'href = "([^".]*)">([^</.]*)' movie.html | awk -F'[">]' 'BEGIN{print "title | link"}{print $4" | "$2}'
grep получит следующие строки:
href = "1%20Buck%20%282017%29/">1 Buck (2017)
href = "1%20Mile%20to%20You%20%282017%29/">1 Mile to You (2017)
href = "1%20Night%20%282016%29/">1 Night (2016)
Добавление в код функций sub() и gsub():
awk -F'[><]' 'BEGIN{ print "title","|", "link" } /%29/ {sub(///, " |", $3);gsub(/^a href = "|"$/, "", $2);print $3,$2}' file
title | link
1 Buck (2017) | 1%20Buck%20%282017%29/
1 Mile to You (2017) | 1%20Mile%20to%20You%20%282017%29/
1 Night (2016) | 1%20Night%20%282016%29/
С file > output:
awk -F'[><]' 'BEGIN{ print "title","|", "link" } /%29/ {sub(///, " |", $3);gsub(/^a href = "|"$/, "", $2);print $3,$2}' file > output.txt
Если ed доступен / приемлем, и вы понимаете риск использования парсера, отличного от html, для анализа файлов hmtl.
script.ed
0a
title | link
.
p
g/^<a href=.\{1,\}/s/^.\{1,\} = "//\
s//[[:blank:]]*</a>.*$//\
s/">/ /\
s/^\([^ ]\{1,\}\) \(.\{1,\}\)/\2 | \1/p
Q
потом
ed -s file.html < script.ed