awk, sed 또는 기타 텍스트 처리 제안 (1A –

필자는 다음과 같은 텍스트 반복 패턴을 사용하여 다시 포맷해야합니다.

일반적으로 이것은 표준 텍스트 편집기를 사용하는 경우에도 쉬워야하지만,이 경우 괄호 안의 정보를 확장하여 열거해야합니다.

가장 좋은 예는 다음과 같습니다.

"Gene Code (1A - 1F) D2 fragment, D74F"

나는 다음과 같이 최종 제품을 보여줄 수 있어야한다.

Gene Code, 1A, D2 fragment, D74F
Gene Code, 1B, D2 fragment, D74F
Gene Code, 1C, D2 fragment, D74F
Gene Code, 1D, D2 fragment, D74F
Gene Code, 1E, D2 fragment, D74F
Gene Code, 1F, D2 fragment, D74F

걸림돌은 괄호 안에 들어있는 초기 문자열이 1A-1F 나 3D-3H 등일 수 있다는 것입니다. 이는 정보를 이동시키는 유일한 방법입니다. 괄호 안의 숫자는 항상 동일하며, 알파벳 문자 만 관련 번호와 함께 확장해야합니다.

그래서 숫자와 알파벳을 연관시키는 것은 필요합니다.

이것은 나에게 마음을 굽히는 것처럼 보입니다. 어떤 도움을 많이 주셨습니다. 그건 그렇고 새로운 것입니다.



답변

이 bash 스크립트

#!/bin/bash

PART1=$(echo "$1" | sed 's/\(.*\)\s(.*/\1/')
PART3=$(echo "$1" | sed 's/.*)\(.*\)/\1/')
PART2=$(echo "$1" | sed 's/.*(\s*\(.*\)).*/\1/')

START=$(echo "$PART2" | sed 's/\s*-.*//')
END=$(echo "$PART2" | sed 's/.*-\s*//')

STARTNUM=$(echo "$START" | sed 's/^\(.\).*/\1/')
ENDNUM=$(echo "$END" | sed 's/^\(.\).*/\1/')
if test "$STARTNUM" '!=' "$ENDNUM"; then
    echo "Error: Numeral is different"
    exit 1
fi

STARTLETTER=$(echo "$START" | sed 's/^.\(.\).*/\1/')
ENDLETTER=$(echo "$END" | sed 's/^.\(.\).*/\1/')

OUTPUT=''
for LETTER in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ; do
    test "$LETTER" '==' "$STARTLETTER" && OUTPUT='yes'
    test -n "$OUTPUT" && echo "$PART1, $STARTNUM$LETTER,$PART3"
    test "$LETTER" '==' "$ENDLETTER" && OUTPUT=''
done

원래 텍스트를 호출 할 때 매우 효과적인 방법이 아니더라도 필요한 것을 할 것입니다. $1

편집하다

요청에 따라 sed 표현 :

  • 나는 격리한다. PART1 공백과 여백 전에 모든 것을 취함으로써 (
  • 나는 격리한다. PART3 종결에서 모든 것을 취함으로써 ) 앞으로
  • 나는 격리한다. PART2 사이에 무엇을 복용하여 (), 공백 무시
  • STARTEND 대시로 구분되며 공백은 무시됩니다.
  • 번호와 문자는 첫 번째 문자와 두 번째 문자로 분리됩니다.

답변

GNU sed를 사용할 수 있다면

sed -r 's/([^(]+) \((.)(.) - .(.)\)(.*)/printf \x27\1, \2%s,\5\\n\x27 {\3..\4}/e' <<<'Gene Code (1A - 1F) D2 fragment, D74F'
Gene Code, 1A, D2 fragment, D74F
Gene Code, 1B, D2 fragment, D74F
Gene Code, 1C, D2 fragment, D74F
Gene Code, 1D, D2 fragment, D74F
Gene Code, 1E, D2 fragment, D74F
Gene Code, 1F, D2 fragment, D74F

그렇지 않다면 파이프로 파이프를 쉘에 보내 실행하십시오.

sed -r 's/([^(]+) \((.)(.) - .(.)\)(.*)/printf \x27\1, \2%s,\5\\n\x27 {\3..\4}/' <<<'Gene Code (1A - 1F) D2 fragment, D74F'|bash
Gene Code, 1A, D2 fragment, D74F
Gene Code, 1B, D2 fragment, D74F
Gene Code, 1C, D2 fragment, D74F
Gene Code, 1D, D2 fragment, D74F
Gene Code, 1E, D2 fragment, D74F
Gene Code, 1F, D2 fragment, D74F

(와 shksh 출력은 동일 함)


답변

펄 방식 :

#!/usr/bin/perl
use feature 'say';

my $str = '"Gene Code (3D - 3H) D2 fragment, D74F"';
# get begin number, begin letter, end number, end letter
my ($bn,$bl,$en,$el) = $str =~ /\((.)(.) - (.)(.)\)/;
# loop from begin letter to end letter
for my $i ($bl .. $el) {
    # do the substitution and print
    ($_ = $str) =~ s/ \(.. - ..\)/, $bn$i,/ && say;
}

산출:

"Gene Code, 3D, D2 fragment, D74F"
"Gene Code, 3E, D2 fragment, D74F"
"Gene Code, 3F, D2 fragment, D74F"
"Gene Code, 3G, D2 fragment, D74F"
"Gene Code, 3H, D2 fragment, D74F"


답변

루핑을 필요로하지 않고 sed에 4 번의 호출만을 사용하는 버전. 맹세 해, 나의 버전은 2 개의 수 치가 동등하다는 것을 검사하지 않는다. 사실, 두 번째 것은 무시되고 심지어 생략 될 수 있습니다. "Gene Code (91K - Q) D2 fragment, D74F". 하한 및 상한은 어느 쪽의 순서로든 나타날 수 있습니다. 하한이 상한보다 큰 경우, 출력 순서가 반대로됩니다.

$ cat foo
#!/usr/bin/env bash

# Script to expand $1 passed as:

# "Gene Code (91K - 91Q) D2 fragment, D74F"
#
# into the output:
#
# Gene Code, 91K, D2 fragment, D74F
# Gene Code, 91L, D2 fragment, D74F
# Gene Code, 91M, D2 fragment, D74F
# Gene Code, 91N, D2 fragment, D74F
# Gene Code, 91O, D2 fragment, D74F
# Gene Code, 91P, D2 fragment, D74F
# Gene Code, 91Q, D2 fragment, D74F


# Copy $1 into FMT_STRING, replacing the " (91K - 91Q)" bit with a ', %s,'
# printf directive, such as 'Gene Code, %s, D2 fragment, D74F':

FMT_STRING="$(sed -e 's/ (.* - .*)/, %s,/' <<< "$1")"

# Parse the beginning and ending bounds and format them with just a
# space between, such as '91K 91Q':

BOUNDS="$(sed -e 's/^[^(]*(\(.*\) - \(.*\)) .*/\1 \2/' <<< "$1")"

# Extract the (first) static numeric part from BOUNDS, e.g. '91'

NUMERIC="$(sed -e 's/[^0-9].*//' <<< "$BOUNDS")"

# remove all digits [0-9] from BOUNDS, e.g. 'K Q'
BOUNDS="$(sed -e 's/[0-9]//g' <<< "$BOUNDS")"

FMT_STRING="$(printf "$FMT_STRING" "${NUMERIC}%c")"

jot -w "$FMT_STRING" - $BOUNDS

샘플 출력 :

$ ./foo "Gene Code (737L - 737X) D2 fragment, D74F"
Gene Code, 737L, D2 fragment, D74F
Gene Code, 737M, D2 fragment, D74F
Gene Code, 737N, D2 fragment, D74F
Gene Code, 737O, D2 fragment, D74F
Gene Code, 737P, D2 fragment, D74F
Gene Code, 737Q, D2 fragment, D74F
Gene Code, 737R, D2 fragment, D74F
Gene Code, 737S, D2 fragment, D74F
Gene Code, 737T, D2 fragment, D74F
Gene Code, 737U, D2 fragment, D74F
Gene Code, 737V, D2 fragment, D74F
Gene Code, 737W, D2 fragment, D74F
Gene Code, 737X, D2 fragment, D74F

범위를 반대로하면 출력이 반전됩니다.

$ ./foo "Gene Code (737X - 737L) D2 fragment, D74F"
Gene Code, 737X, D2 fragment, D74F
Gene Code, 737W, D2 fragment, D74F
Gene Code, 737V, D2 fragment, D74F
Gene Code, 737U, D2 fragment, D74F
Gene Code, 737T, D2 fragment, D74F
Gene Code, 737S, D2 fragment, D74F
Gene Code, 737R, D2 fragment, D74F
Gene Code, 737Q, D2 fragment, D74F
Gene Code, 737P, D2 fragment, D74F
Gene Code, 737O, D2 fragment, D74F
Gene Code, 737N, D2 fragment, D74F
Gene Code, 737M, D2 fragment, D74F
Gene Code, 737L, D2 fragment, D74F


답변