문자열 목록을 소문자로 변경

문자열 목록을 소문자로 변경

두 개의 파일이 있는데 그 중 하나에는 문자열 목록이 포함되어 있습니다.

+stringa +Dog +Cat
+cat +Tux +elephant

두 번째 파일(csv)에는 다음과 유사한 내용이 포함되어 있습니다.

"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +Tux +elephant","Other something"
"34524 xyz","+stringa +Dog +Cat","third something"

결과는 다음과 같습니다.

"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"

내 패턴 목록과 일치하는 문자열을 소문자로 어떻게 변경합니까?

내 쉼표로 구분된 값 파일에는 약 30개의 열과 약 1500개의 행이 있습니다.

답변1

문자열 목록에 기본 BRE 메타 문자 외에 GNU sed메타 문자가 없다고 가정하고 를 사용하세요 .+

$ # create substitute command for each line
$ sed 's/.*/s|"&"|\\L\&|gi/' f1
s|"+stringa +Dog +Cat"|\L&|gi
s|"+cat +Tux +elephant"|\L&|gi

$ # pass those commands as sed script
$ sed -f <(sed 's/.*/s|"&"|\\L\&|gi/' f1) ip.csv
"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"

$ # or save them in a file and use
$ sed 's/.*/s|"&"|\\L\&|gi/' f1 > f2
$ sed -f f2 ip.csv 
  • \L문자열을 소문자로 변환
  • gi대소문자를 구분하지 않고 일치하도록 한 줄의 모든 항목을 바꾸는 데 사용됩니다.


당신이 가지고 있지 않다면GNU sed

$ # \Q to quote metacharacters
$ # but will have issues if you have \ or $ or @
$ sed 's/.*/s|\\Q"&"|\\L$\&|gi;/' f1
s|\Q"+stringa +Dog +Cat"|\L$&|gi;
s|\Q"+cat +Tux +elephant"|\L$&|gi;

$ perl -p <(sed 's/.*/s|\\Q"&"|\\L$\&|gi;/' f1) ip.csv 
"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"


f1Stéphane Chazelas가 지적했듯이 콘텐츠가 제어되지 않으면 코드 삽입 취약점이 발생할 수 있습니다.

답변2

와 함께 perl, 당신이 각각을 원한다고 가정단어소문자로 변환할 첫 번째 파일에서:

perl -pe '
 BEGIN {local $/ = undef; $regex = join "|", map qr{\Q$_\E}i, split " ", <>}
 s/$regex/\L$&/g' file1.words file2.csv

local $/ = undefBEGIN 블록의 레코드 구분 기호를 정의되지 않은 상태로 두어 단일 호출로 <>전체 첫 번째 파일( file1.words)을 해당 블록으로 삼키도록 합니다. 공백으로 분할하고( 에서와 같은 방식 split " ") 결과 단어를 가져온 후의 단어와 비교합니다.perlawk -F " "awk|정규식 참조대소문자를 구분하지 않도록 설정하세요.

(?i:word1)|(?i:word2)|...따라서 나머지 코드에서 두 번째 파일의 모든 줄에 적용하는 것과 유사한 거대한 정규식이 있습니다 .

모든 문자열에 대해철사첫 번째 파일의 경우 다음과 같이 단순화할 수 있습니다.

perl -pe '
 BEGIN {chomp (@strings = <STDIN>); $regex = join "|", map qr{\Q$_\E}i, @strings}
 s/$regex/\L$&/g' < file1.strings file2.csv

여기서는 인수로 전달하는 대신 표준 입력으로 첫 번째 파일을 엽니다. <STDIN>구분 기호를 제거 chomp하고 위와 같이 연결한 행 목록을 반환합니다 |.

-Mopen=localeASCII 문자로 제한되지 않으려면 이 옵션을 추가하십시오 .

답변3

AWK해결 방법(현재 입력의 경우):

두 번째 필드가 주요 초점이고 검색 파일의 값이 큰따옴표로 묶여 있다고 가정합니다.

awk 'NR==FNR{ $0="\042"$0"\042"; a[$0]; next }
     $2 in a{ $2=tolower($2) }1' patterns FS=',' OFS=',' file.csv
  • $0="\042"$0"\042"- 하나 포장무늬patterns파일 라인을 반복할 때 큰따옴표를 사용하는 라인

  • a[$0]- 하나를 캡처무늬행을 배열로a

  • $2 in a{ $2=tolower($2) }- 파일 라인의 두 번째 필드 값이 file.csv패턴 목록(예: 배열 a)에 있는 경우 - 그 안에 있는 모든 문자를 소문자로 변환합니다.$2=tolower($2)


산출:

"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"

관련 정보