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

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

두 개의 파일이 있는데, 한 파일에는 문자열 목록이 포함되어 있습니다.

+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

를 사용하면 GNU sed문자열 목록에 메타 문자가 없고 +기본 BRE의 메타 문자가 아니라고 가정합니다.

$ # 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의 첫 번째 파일을 엽니다. 로 구분 기호를 제거 하고 위와 같이 로 결합하는 <STDIN>행 목록을 반환합니다 .chomp|

ASCII 문자로 제한되지 않도록 하려면 옵션을 추가하세요 -Mopen=locale.

답변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"

관련 정보