다음과 같은 두 개의 데이터 "열"을 포함하는 .csv 파일이 있습니다.
test1.ts.meta,Before Sunrise (1995)
test2.ts.meta,A Beautiful Mind (2001)
test3.ts.meta,Departures (2008)
test4.ts.meta,Love & Other Drugs (2010)
이 명령을 사용하여 각 .ts.meta 파일의 2행을 해당 영화 이름으로 바꾸려고 합니다...
cat 1TBMovie2_dotTSdotMeta.txt | while IFS=, read file moviename; do sed "2 s/^.*$/$moviename/" "$file"; done
영화 이름에 앰퍼샌드(&)가 포함된 점을 제외하면 정상적으로 작동합니다.
예를 들어 영화 제목은 다음과 같습니다.사랑과 마약(2010)이 경우 .ts.meta 파일의 두 번째 줄에 다음 영화 이름이 표시됩니다.
Love Love Love & Other Drugs Other Drugs (2010) Other Drugs (2010)
같은 영화 제목:사랑과 연민(2015).ts.meta 파일에 다음과 같이 나타납니다.사랑 사랑 사랑 그리고 머시 머시(2015) 머시(2015).
혼란스러운 점은...라는 이름의 영화에 대한 .ts.meta 파일을 열면사랑과 연민(2015)2번째 줄을 수동으로 삭제하고 위 명령을 저장한 후 다시 실행했습니다. 2번째 줄에 이 내용이 있습니다...러브 머시(2015)"사랑"과 "자비" 사이에는 두 개의 공백이 있습니다.
$file 변수에서 했던 것처럼 $moviename 변수를 큰따옴표로 묶어야 할까요? sed가 & 문자를 특별한 의미로 취급한다고 생각합니까?
문제를 명확히 하기 위한 추가 정보는 다음과 같습니다.
내 csv 파일(실제로는 updatemeta.txt라고 부름)
test1.ts.meta,Carols from King's (2013)
test2.ts.meta,Before Sunrise (1995)
test3.ts.meta,Love & Other Drugs (2010)
test4.ts.meta,Departures (2008)
test1.ts.meta
1:0:19:1B1C:802:2:11A0000:0:0:0:
Carols from King's
The traditional Christmas carol concert from King's College Chapel, Cambridge. Stephen Cleobury conducts the famous chapel choir in carols old and new. [HD] [S]
1387969020
448066800
2913369072
f:0,c:00157c,c:01157e,c:02157f,c:03157c,c:050001
188
0
test2.ts.meta
1:0:1:189E:7FD:2:11A0000:0:0:0:
Before Sunrise
Romance starring Julie Delpy and Ethan Hawke. Two twentysomethings meet on a train and decide to spend a few hours together. Contains some strong language. Also in HD. [1995] [AD,S]
1392418980
550744512
2637755808
f:0,c:0013ec,c:0113ed,c:0213ef,c:0313ec
188
0
test3.ts.meta
1:0:1:2404:7F9:2:11A0000:0:0:0:
Love & Other Drugs
(2010) Fact-based adult comedy. Jake Gyllenhaal stars as a successful Viagra salesman who falls for a woman with Parkinson's (Anne Hathaway). Strong language/sexual scenes. [AD,S]
1472775840
712401799
2824257448
f:0,c:000931,c:010932,c:020934,c:030931
188
0
test4.ts.yuan
1:0:1:2404:7F9:2:11A0000:0:0:0:
Departures
(2008) An Oscar-winning, whimsical look at the Japanese undertaking profession. Masahiro Motoki stars as a musician starting a new career preparing the dead for burial. Japanese/subs.
1400111580
863881200
3699150040
f:0,c:000931,c:010932,c:020934,c:030931
188
0
.csv 파일을 많은 .ts.meta 파일과 동일한 디렉터리에 넣습니다. 디렉터리의 각 .ts.meta 파일에 대해 .csv 파일에는 해당 영화 이름이 있는 행이 있습니다.
.csv 파일의 각 줄을 반복하고 명명된 .ts.meta 파일의 두 번째 줄을 .csv 파일에 지정된 해당 영화 이름으로 바꾸는 sed, awk 또는 gawk를 사용하는 스크립트를 어떻게 만들 수 있습니까?
아래 솔루션에 제공된 예를 시도했지만 무슨 일이 일어나고 있는지 이해하지 못합니다!
감사합니다,
유연한
답변1
단지 텍스트를 조작하기 위해 쉘 루프를 작성하지 마십시오.쉘 루프를 사용하여 텍스트를 처리하는 것이 나쁜 습관으로 간주되는 이유, 리터럴 문자열을 사용하려면 리터럴 문자열을 이해하지 못하는 sed와 같은 도구보다는 리터럴 문자열을 이해하는 awk와 같은 도구를 사용하십시오.
.ts.meta
테스트할 파일을 제공하지 않았 으므로 분명히 테스트되지 않았지만 비슷한 -i inplace
작업이 GNU awk를 사용하여 수행됩니다(원본 파일을 수정하려는 경우) ARGIND
.
awk -i inplace -F',' '
NR == FNR {
titles[ARGC] = $2
ARGV[ARGC++] = $1
}
(NR != FNR) && (FNR == 2) {
$0 = titles[ARGIND]
}
{ print }
' 1TBMovie2_dotTSdotMeta.txt
정말로 sed로 이 작업을 해보고 싶다면(하지 마세요!) 다음을 참조하세요.sed를 사용하여 정규식 메타문자를 안정적으로 이스케이프하는 것이 가능합니까?그리고 이것이 &
걱정해야 할 유일한 캐릭터가 아니라는 점에 유의하십시오. 예를 들어 처리해야 할 캐릭터 /
도 있습니다.\1
새로 제공된 예제 입력을 고려하면 다음과 같습니다.
$ head -n 50 update* *.meta
==> updatemeta.txt <==
test1.ts.meta,Carols from King's (2013)
test2.ts.meta,Before Sunrise (1995)
test3.ts.meta,Love & Other Drugs (2010)
test4.ts.meta,Departures (2008)
==> test1.ts.meta <==
1:0:19:1B1C:802:2:11A0000:0:0:0:
Carols from King's
The traditional Christmas carol concert from King's College Chapel, Cambridge. Stephen Cleobury conducts the famous chapel choir in carols old and new. [HD] [S]
1387969020
448066800
2913369072
f:0,c:00157c,c:01157e,c:02157f,c:03157c,c:050001
188
0
==> test2.ts.meta <==
1:0:1:189E:7FD:2:11A0000:0:0:0:
Before Sunrise
Romance starring Julie Delpy and Ethan Hawke. Two twentysomethings meet on a train and decide to spend a few hours together. Contains some strong language. Also in HD. [1995] [AD,S]
1392418980
550744512
2637755808
f:0,c:0013ec,c:0113ed,c:0213ef,c:0313ec
188
0
==> test3.ts.meta <==
1:0:1:2404:7F9:2:11A0000:0:0:0:
Love & Other Drugs
(2010) Fact-based adult comedy. Jake Gyllenhaal stars as a successful Viagra salesman who falls for a woman with Parkinson's (Anne Hathaway). Strong language/sexual scenes. [AD,S]
1472775840
712401799
2824257448
f:0,c:000931,c:010932,c:020934,c:030931
188
0
==> test4.ts.meta <==
1:0:1:2404:7F9:2:11A0000:0:0:0:
Departures
(2008) An Oscar-winning, whimsical look at the Japanese undertaking profession. Masahiro Motoki stars as a musician starting a new career preparing the dead for burial. Japanese/subs.
1400111580
863881200
3699150040
f:0,c:000931,c:010932,c:020934,c:030931
188
0
다음은 실행되는 awk 스크립트입니다.
$ awk -i inplace -F',' '
NR == FNR {
titles[ARGC] = $2
ARGV[ARGC++] = $1
}
(NR != FNR) && (FNR == 2) {
$0 = titles[ARGIND]
}
{ print }
' updatemeta.txt
파일에 수행되는 작업은 다음과 같습니다.
$ head -n 50 update* *.meta
==> updatemeta.txt <==
test1.ts.meta,Carols from King's (2013)
test2.ts.meta,Before Sunrise (1995)
test3.ts.meta,Love & Other Drugs (2010)
test4.ts.meta,Departures (2008)
==> test1.ts.meta <==
1:0:19:1B1C:802:2:11A0000:0:0:0:
Carols from King's (2013)
The traditional Christmas carol concert from King's College Chapel, Cambridge. Stephen Cleobury conducts the famous chapel choir in carols old and new. [HD] [S]
1387969020
448066800
2913369072
f:0,c:00157c,c:01157e,c:02157f,c:03157c,c:050001
188
0
==> test2.ts.meta <==
1:0:1:189E:7FD:2:11A0000:0:0:0:
Before Sunrise (1995)
Romance starring Julie Delpy and Ethan Hawke. Two twentysomethings meet on a train and decide to spend a few hours together. Contains some strong language. Also in HD. [1995] [AD,S]
1392418980
550744512
2637755808
f:0,c:0013ec,c:0113ed,c:0213ef,c:0313ec
188
0
==> test3.ts.meta <==
1:0:1:2404:7F9:2:11A0000:0:0:0:
Love & Other Drugs (2010)
(2010) Fact-based adult comedy. Jake Gyllenhaal stars as a successful Viagra salesman who falls for a woman with Parkinson's (Anne Hathaway). Strong language/sexual scenes. [AD,S]
1472775840
712401799
2824257448
f:0,c:000931,c:010932,c:020934,c:030931
188
0
==> test4.ts.meta <==
1:0:1:2404:7F9:2:11A0000:0:0:0:
Departures (2008)
(2008) An Oscar-winning, whimsical look at the Japanese undertaking profession. Masahiro Motoki stars as a musician starting a new career preparing the dead for burial. Japanese/subs.
1400111580
863881200
3699150040
f:0,c:000931,c:010932,c:020934,c:030931
188
0
답변2
한 가지 방법은 정규식 경로를 우회하고 read r
명령을 사용하는 것입니다 sed
.
cat 1TBMovie2_dotTSdotMeta.txt | while IFS=, read file moviename; do printf '%s\n' "$moviename" | sed -i -e '2r /dev/stdin' -e '2d' "$file"; done
다음과 같이 읽을 수 있도록 여러 줄로 작성해야 합니다.
cat 1TBMovie2_dotTSdotMeta.txt |
while IFS=, read file moviename
do
printf '%s\n' "$moviename" |
sed -i -e '2r /dev/stdin' -e '2d' "$file"
done
여기서는 gnu sed 함수를 사용하여 파일을 읽습니다 stdin
. GNU가 아닌 경우 sed
동영상 이름을 임시 파일에 저장하고 해당 이름을 명령에 사용할 수 있습니다 r
. 이제 어떤 것에서도 도망치려고 애쓰지 않아도 됩니다.
그러나 추가 파일의 번거로움을 원하지 않으면 명령 / \ &
의 rhs에서 특수 문자를 이스케이프해야 합니다 sed s/.../.../
. /
구분 기호 역할을 하기 때문에 포함됩니다 .
cat 1TBMovie2_dotTSdotMeta.txt |
while IFS=, read file moviename
do
moviename_esc=$(printf '%s\n' "$moviename" | sed -e 's:[\&/]:\\&:g')
sed -i -e "2 s/.*/$moviename_esc/" "$file"
done