Linux

如何在 sed 命令中正確用雙引號將變數括起來

  • July 8, 2020

我有一個 .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

它工作正常,但電影名稱中包含與號 (&) 除外。

例如電影名稱:**Love & Other Drugs (2010)**在這種情況下,.ts.meta 文件的第二行獲取此電影名稱:

Love Love Love & Other Drugs Other Drugs (2010) Other Drugs (2010)

同樣,電影名稱:**Love & Mercy (2015)**出現在 .ts.meta 文件中,例如:Love Love Love & Mercy Mercy (2015) Mercy (2015)

令人困惑…如果我打開一部名為**Love & Mercy (2015)**的電影的 .ts.meta 文件並手動刪除第 2 行並保存然後再次執行上面的命令,我會在第 2 行得到這個… Love Mercy (2015) “Love”和“Mercy”這兩個詞之間有兩個空格。

我想我需要附上 $ moviename variable in double quotes like I did with the $ 文件變數?我猜&符號被 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.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

我將 .csv 文件與許多 .ts.meta 文件放在同一目錄中。對於目錄中的每個 .ts.meta 文件和對應的電影名稱,.csv 文件中都會有一行。

如何使用 sed 或 awk 或 gawk 創建一個腳本,該腳本循環遍歷 .csv 文件中的每一行,並將命名的 .ts.meta 文件中的第二行替換為 .csv 文件中指定的相應電影名稱?

我嘗試了以下解決方案中給出的範例,但不明白髮生了什麼!

謝謝,

柔性

不要僅僅為了操作文本而編寫 shell 循環,請參閱why-is-using-a-shell-loop-to-process-text-considered-bad-practice,當您想使用文字字元串時,請使用 awk 之類的工具理解文字字元串,而不是像 sed 這樣不理解的工具。

您沒有提供任何.ts.meta文件供我們測試,因此顯然這是未經測試的,但是這樣的事情將使用 GNU awk 完成工作-i inplace(假設您要修改原始文件)和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 執行此操作(不要!),請查看is-it-possible-to-escape-regex-metacharacters-reliably-with-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

引用自:https://unix.stackexchange.com/questions/597286