AWK:从 2 个连续行中加入单独的单词
AWK: join separate words from 2 consecutive lines
我想要一个连接单独单词的 AWK 命令:
1st part is in the end of the line, end up with "_".
2nd part is in the beginning of the next line.
(PS:有些行同时包含第二部分和第一部分,如下例所示)
示例:
Bla bla bla bla SATU_
RDAY bla bla, bla bla
bla bla bla bla bla SUN_
DAY: bla bla bla bla M_
ONDAY. Bla bla bla bla TU_
ESDAY, bla bla bla.
结果:
Line 1: SATURDAY
Line 3: SUNDAY
Line 4: MONDAY
Line 5: TUESDAY
不太确定您的所有要求,但是:
awk 'x {sub("[^A-Z].*", "", ); print "Line "n": "x ; x = ""}
sub("_$", "", $NF) {x = x $NF; n = NF}' input.txt
hth
使用 GNU awk:
$ awk 'p{print gensub(/[^A-Z]$/,"","g",);p=0}/_$/{printf "%s",gensub("_","","g",$NF);p=1}' file
SATURDAY
SUNDAY
MONDAY
TUESDAY
使用 GNU awk 进行多字符 RS:
$ awk -v RS='[[:alpha:]]+_\n[[:alpha:]]+' 'RT!=""{sub(/_\n/,"",RT); print RT}' file
SATURDAY
SUNDAY
MONDAY
TUESDAY
或使用任何 awk:
$ awk 'w{w=w ; gsub(/[^[:alpha:]]/,"",w); print w; w=""} /_$/{w=$NF}' file
SATURDAY
SUNDAY
MONDAY
TUESDAY
如果你真的想要起始行号,那么任何 awk:
$ awk 'w{w=w ; gsub(/[^[:alpha:]]/,"",w); printf "Line %d: %s\n", NR-1, w; w=""} /_$/{w=$NF}' file
Line 1: SATURDAY
Line 3: SUNDAY
Line 4: MONDAY
Line 5: TUESDAY
一个 POSIX 兼容的解决方案:
awk '
firstPart != "" { sub(/[[:punct:]]$/, "", ); print firstPart }
$NF ~ /._$/ { firstPart=substr($NF, 1, length($NF) - 1); next }
{ firstPart= "" }
' file
Pattern(条件)firstPart != ""
仅当在 previous[=61 上找到感兴趣的标记时才为真=] 行,然后才执行关联的 action ({ ... }
):
sub(/[[:punct:]]$/, "", )
替换 (sub()
) 标点字符 ([[:punct:]]
) 的尾随 ($
) 实例,如果有的话,第一个字段 (</code>) 为空字符串,从而有效地删除它。</p></li>
<li><p><code>print firstPart
打印上一行感兴趣的标记与(修改后的)第一个字段的直接连接,只需放置 firstPart
和 </code>彼此相邻,仅由 space.</p></li> 分隔
</ul></li>
<li><p>模式 <code>$NF ~ /._$/
测试最后一个字段 ($NF
) 是否以 ($
) _
结尾(前面至少有 1 个其他字符(.
)).
firstPart=substr($NF, 1, length($NF) - 1)
存储变量 firstPart
. 中除结尾 _
之外的最后一个字段的内容
next
跳过当前行脚本剩余部分的处理并移至下一行。
Action { firstPart= "" }
,因为它前面没有模式,所以被无条件处理 - if reached:
- 只有当手头的行不包含感兴趣的标记时才会到达此处。
- 重置
firstPart
向下一个脚本周期发出信号,表明下一行不会打印任何内容。
$ awk 'p~/_$/{sub(/_$/,"",p);print "Line " (NR-1) ":", p }{p=$NF}' file
Line 1: SATURDAY
Line 3: SUNDAY:
Line 4: MONDAY.
Line 5: TUESDAY,
我想要一个连接单独单词的 AWK 命令:
1st part is in the end of the line, end up with "_".
2nd part is in the beginning of the next line.
(PS:有些行同时包含第二部分和第一部分,如下例所示)
示例:
Bla bla bla bla SATU_
RDAY bla bla, bla bla
bla bla bla bla bla SUN_
DAY: bla bla bla bla M_
ONDAY. Bla bla bla bla TU_
ESDAY, bla bla bla.
结果:
Line 1: SATURDAY
Line 3: SUNDAY
Line 4: MONDAY
Line 5: TUESDAY
不太确定您的所有要求,但是:
awk 'x {sub("[^A-Z].*", "", ); print "Line "n": "x ; x = ""}
sub("_$", "", $NF) {x = x $NF; n = NF}' input.txt
hth
使用 GNU awk:
$ awk 'p{print gensub(/[^A-Z]$/,"","g",);p=0}/_$/{printf "%s",gensub("_","","g",$NF);p=1}' file
SATURDAY
SUNDAY
MONDAY
TUESDAY
使用 GNU awk 进行多字符 RS:
$ awk -v RS='[[:alpha:]]+_\n[[:alpha:]]+' 'RT!=""{sub(/_\n/,"",RT); print RT}' file
SATURDAY
SUNDAY
MONDAY
TUESDAY
或使用任何 awk:
$ awk 'w{w=w ; gsub(/[^[:alpha:]]/,"",w); print w; w=""} /_$/{w=$NF}' file
SATURDAY
SUNDAY
MONDAY
TUESDAY
如果你真的想要起始行号,那么任何 awk:
$ awk 'w{w=w ; gsub(/[^[:alpha:]]/,"",w); printf "Line %d: %s\n", NR-1, w; w=""} /_$/{w=$NF}' file
Line 1: SATURDAY
Line 3: SUNDAY
Line 4: MONDAY
Line 5: TUESDAY
一个 POSIX 兼容的解决方案:
awk '
firstPart != "" { sub(/[[:punct:]]$/, "", ); print firstPart }
$NF ~ /._$/ { firstPart=substr($NF, 1, length($NF) - 1); next }
{ firstPart= "" }
' file
Pattern(条件)
firstPart != ""
仅当在 previous[=61 上找到感兴趣的标记时才为真=] 行,然后才执行关联的 action ({ ... }
):sub(/[[:punct:]]$/, "", )
替换 (sub()
) 标点字符 ([[:punct:]]
) 的尾随 ($
) 实例,如果有的话,第一个字段 (</code>) 为空字符串,从而有效地删除它。</p></li> <li><p><code>print firstPart
打印上一行感兴趣的标记与(修改后的)第一个字段的直接连接,只需放置firstPart
和</code>彼此相邻,仅由 space.</p></li> 分隔 </ul></li> <li><p>模式 <code>$NF ~ /._$/
测试最后一个字段 ($NF
) 是否以 ($
)_
结尾(前面至少有 1 个其他字符(.
)).firstPart=substr($NF, 1, length($NF) - 1)
存储变量firstPart
. 中除结尾 next
跳过当前行脚本剩余部分的处理并移至下一行。
_
之外的最后一个字段的内容Action
{ firstPart= "" }
,因为它前面没有模式,所以被无条件处理 - if reached:- 只有当手头的行不包含感兴趣的标记时才会到达此处。
- 重置
firstPart
向下一个脚本周期发出信号,表明下一行不会打印任何内容。
$ awk 'p~/_$/{sub(/_$/,"",p);print "Line " (NR-1) ":", p }{p=$NF}' file
Line 1: SATURDAY
Line 3: SUNDAY:
Line 4: MONDAY.
Line 5: TUESDAY,