如何使用sed转置单个字符

问题描述

我正在尝试将第3位和第8位换位。尝试使用电话号码:

 /* quiz.service.ts */

getCorrectAnswers(question: QuizQuestion) {
    if (this.question) {
      const identifiedCorrectAnswers = question.options.filter((option) => option.correct);
      this.numberOfCorrectAnswers = identifiedCorrectAnswers.length;
      this.correctAnswerOptions = identifiedCorrectAnswers.map((option) => question.options.indexOf(option) + 1);
      
      /** add this verification */
      const correctAwserAdded = this.correctAnswers.find(q => q.questionId == question.explanation) != undefined;
      if (correctAwserAdded == false) {
        this.correctAnswersForEachQuestion.push(this.correctAnswerOptions);
        this.correctAnswers.push({
          questionId: this.question.explanation,answers: this.correctAnswersForEachQuestion.sort()
        });
      }

      this.setExplanationTextAndCorrectMessages(this.correctAnswerOptions.sort(),this.question);
      return identifiedCorrectAnswers;
    }
  }

换位后:

(888) 747-7424

这就是我所拥有的:

(884) 747-7824

它转置第二和第五位。

解决方法

您只是误算了字符:

$ sed -E 's/(.{3})(.)(.{7})(.)/\1\4\3\2/' file
(884) 747-7824
,

如果您只想交换位数,则需要在任何0个或多个非数字字符之后匹配数字:

sed -E 's/^(([^0-9]*[0-9]){2}[^0-9]*)([0-9])(([^0-9]*[0-9]){4}[^0-9]*)([0-9])/\1\6\4\3/'

请参见online sed demo

s='(888) 747-7424'
sed -E 's/^(([^0-9]*[0-9]){2}[^0-9]*)([0-9])(([^0-9]*[0-9]){4}[^0-9]*)([0-9])/\1\6\4\3/' <<< "$s"
# => (884) 747-7824

详细信息

  • ^-字符串的开头
  • (([^0-9]*[0-9]){2}[^0-9]*)-第1组:两次出现非数字,后跟一个数字,然后是0个或多个非数字
  • ([0-9])-第3组:数字
  • (([^0-9]*[0-9]){4}[^0-9]*)-第4组:出现四次非数字,后跟一个数字,然后是0个或多个非数字
  • ([0-9])-第6组:数字。
,

这可能对您有用(GNU sed):

sed -E 's/[0-9]/\n&/3;s//\n&/8;s/\n(.)(.*)\n(.)/\3\2\1/' file

这将用换行符分隔每个所需的数字,然后使用模式匹配来交换两个数字。

要使其原子化,请使用:

sed -E 's/[0-9]/\n&/8;T;s//\n&/3;s/\n(.)(.*)\n(.)/\3\2\1/' file