두 개의 파일이 있는데, 한 파일에는 문자열 목록이 포함되어 있습니다.
+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
문자열을 소문자로 변환하려면g
i
대소 문자를 구분하지 않는 일치를 위해 한 줄의 모든 항목을 바꾸는 경우
당신이 가지고 있지 않다면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"
f1
Sté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 $/ = undef
BEGIN 블록에 대한 레코드 구분 기호를 정의되지 않은 상태로 만들어 거기서 한 번 호출하면 <>
전체 첫 번째 파일( file1.words
)을 집어넣습니다. 이를 공백으로 분할하고( 와 같은 방식으로 split " "
특수합니다 ) 결과 단어를 다음과 결합합니다. 가지고 난 후에perl
awk -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"