打印前3个字符和/其余带有星号的字符串

时间:2018-10-01 04:43:48

标签: bash awk sed

我有这样的输入

John:boofoo

我想用星号打印字符串的其余部分,并且只保留字符串的3个字符。

输出将是这样

John:boo***

这是我的命令

awk -F ":" '{print $1,$2 ":***"}'

如果可能,我只想使用打印命令。谢谢

9 个答案:

答案 0 :(得分:2)

使用GNU sed:

echo 'John:boofoo' | sed -E 's/(:...).*/\1***/'

输出:

John:boo***

答案 1 :(得分:1)

使用gensub()的GNU awk:

$ awk 'BEGIN{FS=OFS=":"} {print $1, substr($2,1,3) gensub(/./,"*","g",substr($2,4))}' file
John:boo***

任何awk:

awk 'BEGIN{FS=OFS=":"} {tl=substr($2,4); gsub(/./,"*",tl); print $1, substr($2,1,3) tl}' file
John:boo***

答案 2 :(得分:0)

能否请您尝试以下。这将打印星号(仅保持前3个字母不变)在前3个字符之后的第2个字段中有多少个字符。

awk '
BEGIN{
  FS=OFS=":"
}
{
  stars=""
  val=substr($2,1,3)
  for(i=4;i<=length($2);i++){
    stars=stars"*"
  }
  $2=val stars
}
1
'  Input_file

输出如下。

John:boo***

说明: 也在此处添加了上述代码的说明。

awk '
BEGIN{                          ##Starting BEGIN section from here.
  FS=OFS=":"                    ##Setting FS and OFS value as : here.
}                               ##Closing block of BEGIN section here.
{                               ##Here starts main block of awk program.
  stars=""                      ##Nullifying variable stars here.
  val=substr($2,1,3)            ##Creating variable val whose value is 1st 3 letters of 2nd field.
  for(i=4;i<=length($2);i++){   ##Starting a for loop from 4(becasue we need to have from 4th character to till last in 2nd field) till length of 2nd field.
    stars=stars"*"              ##Keep concatenating stars variable to its own value with *.
  }
  $2=val stars                  ##Assigning value of variable val and stars to 2nd field here.
}
1                               ##Mentioning 1 here to print edited/non-edited lines for Input_file here.
' Input_file                    ##Mentioning Input_file name here.

答案 3 :(得分:0)

或者即使年龄不错,sed

$ echo "John:boofoo" | sed 's/...$/***/'

输出:

John:boo***

注意:这只会用"***"替换任何字符串的后3个字符,因此,如果您需要取消':',请参阅GNU {{1 }}来自Cyrus的答案。)

答案 4 :(得分:0)

另一个awk变体:

awk -F ":" '{print $1 FS substr($2, 1, 3) "***"}' <<< 'John:boofoo'

John:boo***

答案 5 :(得分:0)

Another sed : replace all chars after the third by *

sed -E ':A;s/([^:]*:...)(.*)[^*]([*]*)/\1\2\3*/;tA'

答案 6 :(得分:0)

更多awk

awk 'BEGIN{FS=OFS=":"}{s=sprintf("%0*d",length(substr($2,4)),0); gsub(/0/,"*",s);print $1,substr($2,1,3) s}' infile

您可以使用printf%*形式,该形式接受可变宽度。而且,如果您使用“ 0”作为要打印的值,请结合使用左对齐零填充的右对齐文本。

更易读:

awk 'BEGIN{
       FS=OFS=":"
     }
     {
       s=sprintf("%0*d",length(substr($2,4)),0); 
       gsub(/0/,"*",s);
       print $1,substr($2,1,3) s
     }
     ' infile

测试结果:

$ awk --version
GNU Awk 3.1.7
Copyright (C) 1989, 1991-2009 Free Software Foundation.

$ cat f
John:boofoo

$ awk 'BEGIN{FS=OFS=":"}{s=sprintf("%0*d",length(substr($2,4)),0); gsub(/0/,"*",s);print $1,substr($2,1,3) s}' f
John:boo***

答案 7 :(得分:0)

因为我们有标签awk,bash和sed:为完整起见,这里是仅bash的解决方案:

INPUT="John:boofoo"
printf "%s:%s\n" ${INPUT%%:*} $(TMP1=${INPUT#*:};TMP2=${TMP1:3}; echo "${TMP1:0:3}${TMP2//?/*}")

它在格式字符串后使用printf的两个参数。第一个是INPUT,其中除:之后和之后的所有内容都去除了。让我们分解第二个参数$(TMP1=${INPUT#*:};TMP2=${TMP1:3}; echo "${TMP1:0:3}${TMP2//?/*}")

  • $(...)字符串被解释为bash命令,其输出被替换为printf的最后一个参数
    • TMP1=${INPUT#*:};删除:之前的所有内容,并将字符串存储在TMP1中。
    • TMP2=${TMP1:3};TMP1的所有字符从偏移量3到末尾,并将它们存储在TMP2中。
    • echo "${TMP1:0:3}${TMP2//?/*}"输出临时字符串:来自TMP1的前三个字符未修改,来自TMP2的所有字符为*
    • 最后一个回显的输出是printf的最后一个参数

这是bash -x输出:

+ INPUT=John:boofoo
++ TMP1=boofoo
++ TMP2=foo
++ echo 'boo***'
+ printf '%s:%s\n' John 'boo***'
John:boo***

答案 8 :(得分:0)

另一个纯Bash,使用内置的正则表达式谓词。

input="John:boofoo"
if [[ $input =~ ^([^:]*:...)(.*)$ ]]; then
    printf '%s%s\n' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]//?/*}"
else
    echo >&2 "String doesn't match pattern"
fi

我们将字符串分为两部分:第一部分是直到(包括)第一个冒号(存储在${BASH_REMATCH[1]}中)后的三个字符为止的所有内容,第二部分是字符串的其余部分(存储在${BASH_REMATCH[2]}中。如果字符串与该模式不匹配,我们将侮辱用户。

然后,我们将第一部分保持不变,而将第二部分的每个字符替换为*