我正在阅读一行输入,其中包含许多单词,这些单词都以is_tokenized_
开头并且后缀以:TKN_
开头;我的目标是剥离这些前缀和后缀。
我已尝试awk -v RS=" " -F'[_:]' '{print $3}'
,但如果名称本身包含下划线,则无效。
示例输入:
is_tokenized_Firstname:TKN_NAME is_tokenized_Last_Name:TKN_NAME
预期产出:
Firstname Last_Name
答案 0 :(得分:1)
s='is_tokenized_Firstname:TKN_NAME is_tokenized_Last_Name:TKN_NAME'
read -r -a words_in <<<"$s" # Read words into array
for word in "${words_in[@]}"; do # Iterate over input
[[ $word = is_tokenized_*:TKN* ]] && { # Check for match
word=${word#is_tokenized_} # Strip prefixes
word=${word%:TKN*} # Strip suffixes
}
printf '%s ' "$word" # Write output
done
printf '\n'
Parameter expansion是适合这项工作的工具。另请参阅BashFAQ #100(“我如何在bash中进行字符串操作?”)。
read -a
将单词读入由IFS中的字符拆分的数组(默认情况下为空格,制表符和换行符);这样可以轻松操作输入的每个单词。[[ $string = $glob ]]
检查字符串是否与glob样式模式匹配(对于精确的字符串相等性检查,需要使用[[ $string = "$string2" ]]
)。${word#prefix}
展开变量$word
,从头开始删除prefix
。${word%suffix}
也会这样做,最后是后缀。另一种方法,因为你的shell是bash,是使用正则表达式:
re='^is_tokenized_([^:]+):TKN_'
s='is_tokenized_Firstname:TKN_NAME is_tokenized_Last_Name:TKN_NAME'
read -r -a words_in <<<"$s"
for word in "${words_in[@]}"; do
[[ $word =~ $re ]] && word=${BASH_REMATCH[1]}
printf '%s ' "$word"
done
printf '\n'
这是有效的,因为与=~
运算符进行正则表达式匹配会将BASH_REMATCH
变量设置为一个数组,其中第二个项目(索引1,索引0后面)是来自的第一个匹配组手边的正则表达式。
答案 1 :(得分:0)
sed
sed -e 's/is_tokenized_//g' -e 's/:TKN_NAME//g' /tmp/data.txt
Firstname Last_Name
Firstname Last_Name
awk
awk 'BEGIN{ FS="(is_tokenized_|:TKN_NAME)"; OFS=" " } ; {print $2, $4}' /tmp/data.txt
FS
是分割输入字符串的正则表达式; OFS
是输出分隔符的字符串。Firstname Last_Name
Firstname Last_Name