Как перевернуть последний символ строки - PullRequest
0 голосов
/ 29 марта 2019

Я пытаюсь перевернуть последний символ строки между 1 и 2. Мне нужно понять, почему system2 может преобразовать в system1, а system1 не может преобразовать в system2?

echo system2|awk -vFS="" '{if($NF==1) {gsub($NF,2) };if($NF==2)gsub($NF,1)}1'
system1
echo system1|awk -vFS="" '{if($NF==1) {gsub($NF,2) };if($NF==2)gsub($NF,1)}1'
system1

Кроме того, есть ли более умный способ сделать этот бросок?

Ответы [ 4 ]

3 голосов
/ 29 марта 2019

Чтобы сделать это кратко, надежно и переносимо с любым awk, было бы:

$ echo system2| awk '!sub(/1$/,2){sub(/2$/,1)}1'
system1
$ echo system1| awk '!sub(/1$/,2){sub(/2$/,1)}1'
system2
2 голосов
/ 29 марта 2019

Вы можете попробовать следующее (исправление попытки ОП).

echo system1|awk -vFS="" '{if($NF==1){gsub($NF,2);print;next};if($NF==2)gsub($NF,1)}1'

Почему попытка ОП не работает:

Поскольку первое условие - ИСТИНА, а $ NF - 1, оно меняет его на 2, теперь второе условие - ИСТИНА, а 2 снова заменяется на 1, поэтому оно выдает тот же результат.

Моя попытка решить эту проблему будет: Поскольку попытка кода OP очень специфична для GNU awk, поэтому мы можем попробовать выполнить следующее, что может быть более общим решением.

echo system1 | 
awk '
{
   val=substr($0,length($0))
   printf("%s%s\n",substr($0,1,length($0)-1),val==1+0?2:(val==2?1:val))
   val=""
}'
1 голос
/ 29 марта 2019
awk 'BEGIN{FS=OFS=""}($NF==1||$NF==2){$NF=$NF%2+1}1'

Это похоже на подход oguzismail.

  • Изменяется, только если последний символ равен 1 или 2.
  • 1 % 2 + 1 = 22 % 2 + 1 = 1.
1 голос
/ 29 марта 2019

Это потому, что вы меняете $ NF на 2, что делает второе условие верным, и оно снова возвращается к 1. Вам нужен else.

awk -vFS="" '{if($NF==1) {gsub($NF,2) }else if($NF==2)gsub($NF,1)}1'

Я могу придумать немного более простое решение в sed:

sed 's/1$/2/;t;s/2$/1/'

, которая использует команду t, которая (если метка не указана) переходит в конец сценария, если предыдущая замена прошла успешно.

Другое возможное решение использует Perl:

perl -pe 's/([12])$/ $1 =~ tr=12=21=r /e'

Который соответствует последним 1 или 2 и выполняет транслитерацию для него. Вы можете использовать аналогичный трюк с tr в оболочке:

printf '%s' ${string:0:-1}
printf '%s\n' ${string: -1} | tr 12 21

Без выделения вы можете использовать, например, расширение параметров и арифметику:

if [[ $string = *[12] ]] ; then
   echo ${string%[12]}$((3-${string: -1}))
else
    echo $string
fi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...