напечатайте первые 3 символа и / остаток строки со звездами - PullRequest
0 голосов
/ 01 октября 2018

У меня есть такой ввод

John:boofoo

Я хочу напечатать остаток строки со звездами и оставить только 3 символа строки.

Вывод будет таким

John:boo***

это моя команда

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

Я хочу использовать только команду печати, если это возможно.Спасибо

Ответы [ 9 ]

0 голосов
/ 01 октября 2018

С GNU awk для gensub ():

$ 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***
0 голосов
/ 01 октября 2018

Еще один чистый 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]}).Если строка не соответствует этому шаблону, мы просто оскорбляем пользователя.

Затем мы печатаем первую часть без изменений, а вторую часть с каждым символом, замененным на *.

0 голосов
/ 01 октября 2018

Еще немного 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***
0 голосов
/ 01 октября 2018

Так как у нас есть теги 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***
0 голосов
/ 01 октября 2018

Еще один sed: заменить все символы после третьего на *

sed -E ':A;s/([^:]*:...)(.*)[^*]([*]*)/\1\2\3*/;tA'
0 голосов
/ 01 октября 2018

Другой awk вариант:

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

John:boo***
0 голосов
/ 01 октября 2018

Или даже со старым добрым sed

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

Вывод:

John:boo***

( note : это просто заменяет последние 3 символа любой строкис "***", поэтому, если вам нужно отключить ':', см. ответ GNU sed от Cyrus.)

0 голосов
/ 01 октября 2018

Не могли бы вы попробовать следующее.Это будет печатать звездочки (оставляя только первые 3 буквы такими же, как есть), сколько символов присутствует во 2-м поле после первых 3 символов.

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.
0 голосов
/ 01 октября 2018

С GNU sed:

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

Выход:

John:boo***
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...