使用 awk 命令打印每个单词的最后一个字母以生成字符串
print the last letter of each word to make a string using `awk` command
我有这条线
UDACBG UYAZAM DJSUBU WJKMBC NTCGCH DIDEVO RHWDAS
我正在尝试使用 awk
命令打印每个单词的最后一个字母以创建一个字符串
awk '{ print substr(,6) substr(,6) substr(,6) substr(,6) substr(,6) substr(,6) }'
如果我不知道一个单词包含多少个字符,打印 $column 的最后一个字符的正确命令是什么,而不是重复 substr
命令,我该如何使用它仅一次打印不同列中的特定字符
如果您只有这一行要处理,您可以使用
awk '{for (i=1;i<=NF;i++) r = r "" substr($i,length($i))} END{print r}' file
如果输入多行:
awk '{r=""; for (i=1;i<=NF;i++) r = r "" substr($i,length($i)); print r}' file
详情:
{for (i=1;i<=NF;i++) r = r "" substr($i,length($i))
- 遍历当前记录中的所有字段,i
是字段 ID,$i
是字段值,每个字段的所有最后一个字符(检索substr($i,length($i))
) 附加到 r
变量
END{print r}
在 awk
脚本完成处理后打印 r
变量。
- 在第二种解决方案中,
r
值在每行处理开始时被清除,并在处理完当前记录中的所有字段后打印其值。
参见 online demo:
#!/bin/bash
s='UDACBG UYAZAM DJSUBU WJKMBC NTCGCH DIDEVO RHWDAS'
awk '{for (i=1;i<=NF;i++) r = r "" substr($i,length())} END{print r}' <<< "$s"
输出:
GMUCHOS
使用 GNU awk 和 gensub
:
$ gawk '{print gensub(/([^ ]+)([^ ])( |$)/,"\2","g")}' file
输出:
GMUCHOS
第一个解决方案: 使用 GNU awk
你可以尝试遵循 awk
程序,编写并测试显示示例。
awk -v RS='.([[:space:]]+|$)' 'RT{gsub(/[[:space:]]+/,"",RT);val=val RT} END{print val}' Input_file
说明: 将记录分隔符设置为任何字符后跟 space 或 value/line 的结尾。然后根据 OP 的要求从获取的值中删除不必要的 newline/spaces ;继续创建具有 RS 匹配值的 val,最后当 awk
程序完成读取整个 Input_file 然后打印变量的值。
第二个解决方案: 使用记录分隔符作为 null 并在值上使用 match
函数以匹配正则表达式 (.[[:space:]]+)|(.$)
要仅在找到每个匹配项时获取最后一个字母值,请继续将匹配值添加到变量中,最后在 awk
程序打印变量值的 END 块中。
awk -v RS= '
{
while(match([=11=],/(.[[:space:]]+)|(.$)/)){
val=val substr([=11=],RSTART,RLENGTH)
[=11=]=substr([=11=],RSTART+RLENGTH)
}
}
END{
gsub(/[[:space:]]+/,"",val)
print val
}
' Input_file
sed 的任务是在单行上进行简单替换:
$ sed 's/[^ ]*\([^ ]\) *//g' file
GMUCHOS
GNU awk 的另一种方法是使用 FPAT
到 split by and keep the content:
gawk 'BEGIN{FPAT="\S\>"}
{ s=""
for (i=1; i<=NF; i++) s=s $i
print s
}' file
GMUCHOS
或者更简洁和地道的:
gawk 'BEGIN{FPAT="\S\>";OFS=""}{=}1' file
GMUCHOS
(感谢大维)
您还可以将 gensub 用于:
gawk '{print gensub(/\S*(\S\>)\s*/,"\1","g")}' file
GMUCHOS
两者的优点是单个字母“单词”处理得当:
s2='SINGLE X LETTER Z'
gawk 'BEGIN{FPAT="\S\>";OFS=""}{=}1' <<< "$s2"
EXRZ
gawk '{print gensub(/\S*(\S\>)\s*/,"\1","g")}' <<< "$s2"
EXRZ
哪里接受的答案和大多数在这里不:
awk '{for (i=1;i<=NF;i++) r = r "" substr($i,length())} END{print r}' <<< "$s2"
ER # WRONG
gawk '{print gensub(/([^ ]+)([^ ])( |$)/,"\2","g")}' <<< "$s2"
EX RZ # WRONG
使用很多工具
$ tr -s ' ' '\n' <file | rev | cut -c1 | paste -sd'[=10=]'
GMUCHOS
将单词分隔成行,反转以便我们可以轻松选择第一个字符,最后将它们重新粘贴在一起而不使用分隔符。不是最短的解决方案,但我认为是最简单的解决方案...
我将如下利用 GNU AWK
,令 file.txt
内容为
UDACBG UYAZAM DJSUBU WJKMBC NTCGCH DIDEVO RHWDAS
然后
awk 'BEGIN{FPAT="[[:alpha:]]\>";OFS=""}{=;print}' file.txt
输出
GMUCHOS
解释:通知AWK 处理单词末尾的任何字母字符,并使用空字符串作为输出字段分隔符。 =
用于通过使用指定的 OFS
来触发线路重建。如果您想了解更多关于 start/end 的信息,请阅读 GNU Regexp Operators.
(在 gawk 4.2.1 中测试)
另一个 GNU 解决方案 awk
:
awk '{[=10=]=gensub(/[^[:space:]]*([[:alpha:]])/, "\1","g"); gsub(/\s/,"")} 1' file
GMUCHOS
gensub()
获取字符,gsub()
删除它们之间的空格。
或使用patsplit()
:
awk 'n=patsplit([=11=], a, /[[:alpha:]]\>/) { for (i in a) printf "%s", a[i]} i==n {print ""}' file
GMUCHOS
我有这条线
UDACBG UYAZAM DJSUBU WJKMBC NTCGCH DIDEVO RHWDAS
我正在尝试使用 awk
命令打印每个单词的最后一个字母以创建一个字符串
awk '{ print substr(,6) substr(,6) substr(,6) substr(,6) substr(,6) substr(,6) }'
如果我不知道一个单词包含多少个字符,打印 $column 的最后一个字符的正确命令是什么,而不是重复 substr
命令,我该如何使用它仅一次打印不同列中的特定字符
如果您只有这一行要处理,您可以使用
awk '{for (i=1;i<=NF;i++) r = r "" substr($i,length($i))} END{print r}' file
如果输入多行:
awk '{r=""; for (i=1;i<=NF;i++) r = r "" substr($i,length($i)); print r}' file
详情:
{for (i=1;i<=NF;i++) r = r "" substr($i,length($i))
- 遍历当前记录中的所有字段,i
是字段 ID,$i
是字段值,每个字段的所有最后一个字符(检索substr($i,length($i))
) 附加到r
变量END{print r}
在awk
脚本完成处理后打印r
变量。- 在第二种解决方案中,
r
值在每行处理开始时被清除,并在处理完当前记录中的所有字段后打印其值。
参见 online demo:
#!/bin/bash
s='UDACBG UYAZAM DJSUBU WJKMBC NTCGCH DIDEVO RHWDAS'
awk '{for (i=1;i<=NF;i++) r = r "" substr($i,length())} END{print r}' <<< "$s"
输出:
GMUCHOS
使用 GNU awk 和 gensub
:
$ gawk '{print gensub(/([^ ]+)([^ ])( |$)/,"\2","g")}' file
输出:
GMUCHOS
第一个解决方案: 使用 GNU awk
你可以尝试遵循 awk
程序,编写并测试显示示例。
awk -v RS='.([[:space:]]+|$)' 'RT{gsub(/[[:space:]]+/,"",RT);val=val RT} END{print val}' Input_file
说明: 将记录分隔符设置为任何字符后跟 space 或 value/line 的结尾。然后根据 OP 的要求从获取的值中删除不必要的 newline/spaces ;继续创建具有 RS 匹配值的 val,最后当 awk
程序完成读取整个 Input_file 然后打印变量的值。
第二个解决方案: 使用记录分隔符作为 null 并在值上使用 match
函数以匹配正则表达式 (.[[:space:]]+)|(.$)
要仅在找到每个匹配项时获取最后一个字母值,请继续将匹配值添加到变量中,最后在 awk
程序打印变量值的 END 块中。
awk -v RS= '
{
while(match([=11=],/(.[[:space:]]+)|(.$)/)){
val=val substr([=11=],RSTART,RLENGTH)
[=11=]=substr([=11=],RSTART+RLENGTH)
}
}
END{
gsub(/[[:space:]]+/,"",val)
print val
}
' Input_file
sed 的任务是在单行上进行简单替换:
$ sed 's/[^ ]*\([^ ]\) *//g' file
GMUCHOS
GNU awk 的另一种方法是使用 FPAT
到 split by and keep the content:
gawk 'BEGIN{FPAT="\S\>"}
{ s=""
for (i=1; i<=NF; i++) s=s $i
print s
}' file
GMUCHOS
或者更简洁和地道的:
gawk 'BEGIN{FPAT="\S\>";OFS=""}{=}1' file
GMUCHOS
(感谢大维
您还可以将 gensub 用于:
gawk '{print gensub(/\S*(\S\>)\s*/,"\1","g")}' file
GMUCHOS
两者的优点是单个字母“单词”处理得当:
s2='SINGLE X LETTER Z'
gawk 'BEGIN{FPAT="\S\>";OFS=""}{=}1' <<< "$s2"
EXRZ
gawk '{print gensub(/\S*(\S\>)\s*/,"\1","g")}' <<< "$s2"
EXRZ
哪里接受的答案和大多数在这里不:
awk '{for (i=1;i<=NF;i++) r = r "" substr($i,length())} END{print r}' <<< "$s2"
ER # WRONG
gawk '{print gensub(/([^ ]+)([^ ])( |$)/,"\2","g")}' <<< "$s2"
EX RZ # WRONG
使用很多工具
$ tr -s ' ' '\n' <file | rev | cut -c1 | paste -sd'[=10=]'
GMUCHOS
将单词分隔成行,反转以便我们可以轻松选择第一个字符,最后将它们重新粘贴在一起而不使用分隔符。不是最短的解决方案,但我认为是最简单的解决方案...
我将如下利用 GNU AWK
,令 file.txt
内容为
UDACBG UYAZAM DJSUBU WJKMBC NTCGCH DIDEVO RHWDAS
然后
awk 'BEGIN{FPAT="[[:alpha:]]\>";OFS=""}{=;print}' file.txt
输出
GMUCHOS
解释:通知AWK 处理单词末尾的任何字母字符,并使用空字符串作为输出字段分隔符。 =
用于通过使用指定的 OFS
来触发线路重建。如果您想了解更多关于 start/end 的信息,请阅读 GNU Regexp Operators.
(在 gawk 4.2.1 中测试)
另一个 GNU 解决方案 awk
:
awk '{[=10=]=gensub(/[^[:space:]]*([[:alpha:]])/, "\1","g"); gsub(/\s/,"")} 1' file
GMUCHOS
gensub()
获取字符,gsub()
删除它们之间的空格。
或使用patsplit()
:
awk 'n=patsplit([=11=], a, /[[:alpha:]]\>/) { for (i in a) printf "%s", a[i]} i==n {print ""}' file
GMUCHOS