교체하기 전에 추가 일치를 허용하려면 sed에서 이름을 바꿉니다.

교체하기 전에 추가 일치를 허용하려면 sed에서 이름을 바꿉니다.

.txt 파일을 사용하여 fileA의 텍스트 이름을 바꾸려고 합니다 sed. 두 번째 열은 fileA제품 이름에 대한 전체 설명입니다. 제품 이름을 제품 ID로 바꾸고 싶습니다. 그러나 설명의 일부 텍스트에는 유사한 내용이 있습니다(예 fileA: ). "오렌지 주스"는 2행과 4행에 두 번 나타납니다.

renamefile제품 이름 을 sed.sed

파일 A:

AB12345    100    0    Apple juice 20/05   AB
CD67890    150    0    Orange juice with pulp 22/05   CS
EF25879    100    0    Watermelon juice 19/05   CG
GH96314    98    0    Orange juice 20/05   PU
IJ74123    95    0    Strawberry juice with lemon 17/05   ST

파일 이름을 바꿉니다.

s/\<Apple juice\>/3071/g
s/\<Orange juice with pulp\>/3072/g
s/\<Orange juice\>/3073/g
s/\<Watermelon juice\>/3074/g
s/\<Apple juice with lemon\>/3075/g
s/\<Strawberry juice with lemon\>/3076/g

현재 출력:

AB12345    100    0    3071 20/05   AB
CD67890    150    0    **3073** 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

원하는 출력:

AB12345    100    0    3071 20/05   AB
CD67890    150    0    3072 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

나는 정확히 일치하는 경우에만 교체에 도움이 된다는 것을 어딘가에서 발견했기 때문에 "<>"를 사용하고 있습니다. 그러나 이 경우에는 작동하지 않는 것 같습니다. (오류는 현재 출력에서 ​​굵게 표시됩니다.)

문자열 교체에서 처음 두 문자열이 일치한 후 더 많은 단어를 고려하고 해당 이름을 해당 ID로 바꾸는 더 좋고 효율적인 방법이 있습니까?

내가 충분히 명확하지 않다면 말해주십시오. 감사해요!

답변1

renamefile길이를 기준으로 재정렬 해야 하며 긴 이름을 먼저 교체해야 합니다.

awk '{ print length, $0 }' renamefile| sort -nr | cut -d" " -f2- > renamefile2

산출

s/\<Strawberry juice with lemon\>/3076/g
s/\<Orange juice with pulp\>/3072/g
s/\<Apple juice with lemon\>/3075/g
s/\<Watermelon juice\>/3074/g
s/\<Orange juice\>/3073/g
s/\<Apple juice\>/3071/g

그럼 문제없이 신청하실 수 있어요

sed -f renamefile2 fileA

설명하다:

awk루프 행

  • lengthawk에 내장된 함수입니다. 인수 없이 호출하면 현재 줄의 크기를 인쇄합니다(자세한 내용은이상한 길이)
  • $0현재 행

다음 명령은 줄 자체 옆에 있는 각 줄의 길이를 인쇄합니다.

awk '{ print length, $0 }' renamefile

24 s/\<Apple juice\>/3071/g
35 s/\<Orange juice with pulp\>/3072/g
25 s/\<Orange juice\>/3073/g

sort입력된 텍스트가 정렬됩니다.

  • -n숫자순으로 정렬됩니다
  • -r결과가 아래로 향하도록 반전합니다.

cut텍스트의 일부를 선택합니다(최종 스크립트에서는 길이가 필요하지 않고 sed줄의 일부만 선택하면 되므로).

  • -d" "여기에 구분 기호를 지정합니다 space.
  • -f2-필드 2부터 라인 끝까지

답변2

/제품 이름 뒤에 항상 두 자리 숫자, 한 자리 숫자, 다시 두 자리 숫자가 오면 정규식으로 묶고 역참조를 사용하여 그 자체로 바꿀 수 있습니다.

앞의 4개 공백 문자를 일치시켜 해당 문자로 바꿀 수도 있습니다.

파일 이름을 바꿉니다.

s/( {4})Apple juice( [[:digit:]]{2}\/[[:digit:]]{2})/\13071\2/
s/( {4})Orange juice with pulp( [[:digit:]]{2}\/[[:digit:]]{2})/\13072\2/
s/( {4})Orange juice( [[:digit:]]{2}\/[[:digit:]]{2})/\13073\2/
s/( {4})Watermelon juice( [[:digit:]]{2}\/[[:digit:]]{2})/\13074\2/
s/( {4})Apple juice with lemon( [[:digit:]]{2}\/[[:digit:]]{2})/\13075\2/
s/( {4})Strawberry juice with lemon( [[:digit:]]{2}\/[[:digit:]]{2})/\13076\2/

산출:

$ sed -Ef renamefile fileA
AB12345    100    0    3071 20/05   AB
CD67890    150    0    3072 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

답변3

awk를 사용하는 것이 더 쉽습니다.

$ cat tst.awk
BEGIN {
    id = 3071
    map["Apple juice"]                  = id++
    map["Orange juice with pulp"]       = id++
    map["Orange juice"]                 = id++
    map["Watermelon juice"]             = id++
    map["Apple juice with lemon"]       = id++
    map["Strawberry juice with lemon"]  = id++
}
match($0,/^((\S+\s+){3})(.*\S)((\s+\S+){2})/,a) {
    $0 = a[1] map[a[3]] a[4]
    print
}

$ awk -f tst.awk file
AB12345    100    0    3071 20/05   AB
CD67890    150    0    3072 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

\<위의 내용은 GNU sed 및 \>단어 경계를 사용하기 때문에 GNU awk를 사용합니다 .

답변4

GNU sed를 사용하여 먼저 이름 바꾸기 파일을 동적으로 수정한 다음(수동 편집을 수행할 필요가 없음을 의미) 이를 sed 코드로 사용하여 파일 A에서 편집을 수행합니다.

이름이 바뀐 파일에서 변경한 사항은 \> 대신 RHS 경계로 개행을 찾는 것이었습니다. 하지만 그 전에 fileA의 패턴 공간에 개행 문자를 삽입합니다.

$ sed -re '
     1i\
s/(\\s+\\S+){2}\\s*$/\\n&/
     s/\\>/\\n/
' renamefile | sed -rf - fileA

산출:

AB12345    100    0    3071 20/05   AB
CD67890    150    0    3072 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

관련 정보