我有这样的输入
John:boofoo
我想用星号打印字符串的其余部分,并且只保留字符串的3个字符。
输出将是这样
John:boo***
这是我的命令
awk -F ":" '{print $1,$2 ":***"}'
如果可能,我只想使用打印命令。谢谢
答案 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]}
中。如果字符串与该模式不匹配,我们将侮辱用户。
然后,我们将第一部分保持不变,而将第二部分的每个字符替换为*
。