从匹配模式的shell单词中去除前缀​​和后缀

时间:2015-12-22 14:23:01

标签: bash shell

我正在阅读一行输入,其中包含许多单词,这些单词都以is_tokenized_开头并且后缀以:TKN_开头;我的目标是剥离这些前缀和后缀。

我已尝试awk -v RS=" " -F'[_:]' '{print $3}',但如果名称本身包含下划线,则无效。

示例输入:

is_tokenized_Firstname:TKN_NAME is_tokenized_Last_Name:TKN_NAME

预期产出:

Firstname Last_Name

2 个答案:

答案 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