我有一个由HTML代码组成的文本文件,我需要操作它以使其更具可读性。我的问题是我的每个文件名都有两行并不是唯一的,但我需要区分它们:
编辑
我会把输入放在那些要求它的人身上:
<body>
<tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="HAPPY/3_step_minimal_foundation_no_prefill_HAPPY">3_step_minimal_foundation_no_prefill_HAPPY</a></td></tr>
<tr><td><a href="HAPPY/fullform_no_prefill_HAPPY">fullform_no_prefill_HAPPY</a></td></tr>
<tr><td><a href="HAPPY/fullform_mobile_foundation_no_prefill_HAPPY">fullform_mobile_foundation_no_prefill_HAPPY</a></td></tr>
<tr><td><a href="SAD/3_step_minimal_foundation_SAD">3_step_minimal_foundation_SAD</a></td></tr>
<tr><td><a href="SAD/fullform_SAD">fullform_SAD</a></td></tr>
<tr><td><a href="SAD/fullform_mobile_foundation_SAD">fullform_mobile_foundation_SAD</a></td></tr>
<tr><td><a href="HAPPY_PLUS_OPTIONS/3_step_minimal_foundation_HAPPY_PLUS_OPTIONS">3_step_minimal_foundation_HAPPY_PLUS_OPTIONS</a></td></tr>
<tr><td><a href="HAPPY_PLUS_OPTIONS/fullform_HAPPY_PLUS_OPTIONS">fullform_HAPPY_PLUS_OPTIONS</a></td></tr>
<tr><td><a href="HAPPY_PLUS_OPTIONS/fullform_mobile_foundation_HAPPY_PLUS_OPTIONS">fullform_mobile_foundation_HAPPY_PLUS_OPTIONS</a></td></tr>
<tr><td><a href="SAD_PLUS_OPTIONS/3_step_minimal_foundation_SAD_PLUS_OPTIONS">3_step_minimal_foundation_SAD_PLUS_OPTIONS</a></td></tr>
<tr><td><a href="SAD_PLUS_OPTIONS/fullform_SAD_PLUS_OPTIONS">fullform_SAD_PLUS_OPTIONS</a></td></tr>
<tr><td><a href="SAD_PLUS_OPTIONS/fullform_mobile_foundation_SAD_PLUS_OPTIONS">fullform_mobile_foundation_SAD_PLUS_OPTIONS</a></td></tr>
</tbody></table>
</body>
3_step_minimal_foundation_no_prefill_HAPPY
和
3_step_minimal_foundation_no_prefill_HAPPY
例如需要成为:
3_step_minimal_foundation_no_prefill
和
3_step_minimal_foundation_no_prefill_HAPPY
我目前的文本文件状态:
这是我实现的代码:
$ sed -n '/ref/p' EVERYTHING | awk -F'[/"<> ]+' '{sub("", "", $6); print $6, $7, $8}' | tr -s '[[:space:]]' '\n' | awk -v n=3 '1; NR % n == 0 {print ""}' | sed '/^HAPPY/s/^/Flow Type\: /' | sed '/^SAD/s/^/Flow Type\: /' | sed '$d'
Flow Type: HAPPY
3_step_minimal_foundation_no_prefill_HAPPY
3_step_minimal_foundation_no_prefill_HAPPY
Flow Type: HAPPY
fullform_no_prefill_HAPPY
fullform_no_prefill_HAPPY
Flow Type: HAPPY
fullform_mobile_foundation_no_prefill_HAPPY
fullform_mobile_foundation_no_prefill_HAPPY
Flow Type: SAD
3_step_minimal_foundation_SAD
3_step_minimal_foundation_SAD
Flow Type: SAD
fullform_SAD
fullform_SAD
Flow Type: SAD
fullform_mobile_foundation_SAD
fullform_mobile_foundation_SAD
Flow Type: HAPPY_PLUS_OPTIONS
3_step_minimal_foundation_HAPPY_PLUS_OPTIONS
3_step_minimal_foundation_HAPPY_PLUS_OPTIONS
Flow Type: HAPPY_PLUS_OPTIONS
fullform_HAPPY_PLUS_OPTIONS
fullform_HAPPY_PLUS_OPTIONS
我想要的输出:
Flow Type: HAPPY
Flow Name: 3_step_minimal_foundation_no_prefill
File Name: 3_step_minimal_foundation_no_prefill_HAPPY
Flow Type: HAPPY
Flow Name: fullform_no_prefill
File Name: fullform_no_prefill_HAPPY
Flow Type: HAPPY
Flow Name: fullform_mobile_foundation_no_prefill
File Name: fullform_mobile_foundation_no_prefill_HAPPY
Flow Type: SAD
Flow Name: 3_step_minimal_foundation
File Name: 3_step_minimal_foundation_SAD
Flow Type: SAD
Flow Name: fullform
File Name: fullform_SAD
Flow Type: SAD
Flow Name: fullform_mobile_foundation
File Name: fullform_mobile_foundation_SAD
Flow Type: HAPPY_PLUS_OPTIONS
Flow Name: 3_step_minimal_foundation
File Name: 3_step_minimal_foundation_HAPPY_PLUS_OPTIONS
Flow Type: HAPPY_PLUS_OPTIONS
Flow Name: fullform
File Name: fullform_HAPPY_PLUS_OPTIONS
有没有办法可以删除/保留编号为N的特定文本?一旦我得到每一行都是唯一的,就可以很容易地正确标记每一行。
- 最佳
答案 0 :(得分:2)
要求救援
awk 'BEGIN{RS="\n\n"; h="\nFile Name: "}{gsub("_"$3,"",$4); $4=h$4; $5=h$5"\n"; print}'
最后加一个空行。如果重要的话,您可以使用一些额外的逻辑来修剪它,或者只是将输出汇总到sed '$d'
或head -n -1
带评论的修订版(thx to Tom Fenech)
awk -vRS= '{ # set awk to paragraph mode
sub("_" $3, "", $4) # remove name from field suffix
$4 = "\nFlow Name: " $4 # construct new fields with header and newline
$5 = "\nFile Name: " $5 "\n" # extra new line for record separation
print # print all fields
}'
没有多少。您将记录定义为完整的文本块,而不是每行(这解决了问题的一半)。根据您的格式,我们可以通过索引引用各个字段。从定义为另一个字段的一个字段中删除后缀,并准备带标题的其他字段。
答案 1 :(得分:2)
好的,对于从下划线到行尾的所有内容的基本功能,对于与前一行匹配的行,这个过程非常简单。以下是两个选项,100%未经测试。
在awk中:
awk '$0 == last { sub(/_[^_]+$/,""); } { last=$0; } 1' inputfile
在shell中:
while read line; do
if [ "$line" = "$last" ]; then
line="${line%_*}"
fi
echo "$line"
last="$line"
done < inputfile
但这改变了两行的 second 。对于您需要的其他格式,您似乎想要修改两行的第一个。这使得这更加复杂......
要从您拥有的文本转到您想要的文本,让我们以不同的方式看待它,并假设在以“Flow Type”开头的行之后出现两条重复的行 :”
awk '
/^Flow Type:/ {
print;
getline one; getline two
if (one == two) {
sub(/_[^_]+$/,"",one);
print "Flow Name: " one;
print "File Name: " two;
} else {
print one; print two
}
next;
}
1
' inputfile
但我们也可以处理原始HTML。
在sed中,模式识别非常有趣。这是GNU sed中的一个:
sed -r 's|<tr><td><a href="([^/]+)/(([^"]+)_[^_]+)".*|Flow Type: \1\nFlow Name: \3\nFile Name: \2|' input.html
这是需要GNU sed的新行(\n
);结构上它只是简单的sed。此解决方案不适用于* BSD或OSX。
编辑:根据对Potong的回答的评论,在OSX中可以使用的变体是这样的:
<input.html sed -n 's/^.*"\([^"\/]*\)\/\(\([^"]*\)_\1\)".*/Flow Type: \1|Flow Name: \3|File Name: \2|/p' | tr '|' '\n'`
或者如果您更喜欢ERE而不是BRE:
<input.html sed -E 's|<tr><td><a href="([^/]+)/(([^"]+)_[^_]+)".*|Flow Type: \1#Flow Name: \3#File Name: \2#|' | tr '#' '\n'
这解决了OSX sed无法在 s ubstitute的替换字符串中插入换行符的限制。相反,我们插入一个未使用的字符,并使用tr
将其转换为换行符。
要在awk中实现相同的目标(即处理HTML),您可能会使用以下内容:
awk '
/<tr><td><a/ {
type=$0; file=$0;
sub(/^[^"]+/,"",type); sub(/\/.*/,"",type);
sub(/^[^\/]+\//,"",file); sub(/".*/,"",file);
name=file; sub(/_[^_]+$/,"",name);
printf("Flow type: %s\nFlow name: %s\nFile name: %s\n\n", type, name, file);
}' input.html
好的,这是我的最后一次更新。这是你在找什么?
awk '
/<tr><td><a/ {
type=$0; sub(/^[^"]+"/,"",type); sub(/\/.*/,"",type);
file=$0; sub(/^[^\/]+\//,"",file); sub(/".*/,"",file);
if ( index(file, type) ) {
name=substr(file, 0, index(file, type)-2);
} else {
name=file; sub(/_[^_]+$/,"",name);
}
printf("Flow type: %s\nFlow name: %s\nFile name: %s\n\n", type, name, file);
}'
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed -nr 's/^.*"([^"\/]*)\/(([^"]*)_\1)".*/Flow Type: \1\nFlow Name: \3\nFile Name: \2\n/p' file
使用扩展的正则表达式,不要自动打印每一行。匹配所需的字符串并使用反向引用来提取所需的输出。仅在成功替换时打印。
可能适用于其他sed的替代解决方案:
sed -n -e 'G' -e 's/^.*"\([^"\/]*\)\/\(\([^"]*\)_\1\)".*\(.\)/Flow Type: \1\4Flow Name: \3\4File Name: \2\4/p' file
答案 3 :(得分:0)
awk '
/<tr><td><a/ {
type=$0; file=$0;
sub(/^[^S|^H]+/,"",type); sub(/\/.*/,"",type);
sub(/^[^\/]+\//,"",file); sub(/".*/,"",file);
name=file; sub(/_[^fullform|^prefill]+$/,"",name);
printf("Flow type: %s\nFlow name: %s\nFile name: %s\n\n", type, name, file);
}’ Filename.txt
这是我为我的解决方案提出的。它适用于我需要的东西。我最终指定了切断的实际字符串,现在这很好。在未来,我将改进此解决方案,使其更加向前兼容。谢谢大家的帮助!