2016-02-15 100 views
0

我做了一個shell腳本,我可以使用我的播放列表爲MPD。我用它來按文件夾和藝術家編寫歌曲,但是當我嘗試使用awk刪除腳本末尾的重複項時,輸出變爲空。在shell腳本中包含awk使輸出爲空?

繼承人的腳本:

(
mpc search artist 'Black Coast' && 
mpc search artist 'ASTR' && 
ls ~/music/HDD/Chill | awk '$0="HDD/Chill/"$0' 
) | tee testi.txt; 
awk '!v[$0]++' testi.txt | tee testi.txt 

awk的上述前綴字符串正確但是如果我添加了產量低於AWK是一個空文件。但是,該行在腳本文件之外工作。

編輯:它的工作原理與

(
mpc search artist 'Black Coast' && 
mpc search artist 'ASTR' && 
ls ~/music/HDD/Chill | awk '$0="HDD/Chill/"$0' 
) | awk '!v[$0]++' | tee testi.txt 

所以我quess改爲爲什麼上面的例子不能正常工作的問題?

+0

爲什麼兩個'tee's?爲什麼你有一個臨時文件? –

+0

如果你有GNU awk,你可以進行就地編輯。還有moreutils的海綿:http://unix.stackexchange.com/a/207921/70524 – muru

回答

0

您正在寫信給您正在閱讀的文件。從來沒有這樣做,因爲殼可以在閱讀之前寫下它。你想這樣(未經)SOMETHING:

(awk '!v[$0]++' testi.txt | tee tmp.txt) && mv tmp.txt testi.txt 
+0

所以它基本上是異步的? – RusinaRange

+0

idk如果這是我爲它選擇的術語,但是當您使用相同的命令讀取和寫入同一文件時,由shell決定讀取哪個命令和寫入哪個命令。谷歌是你的朋友... –

0

我想這裏的問題是,你的輸入和輸出文件是相同的。這會導致它在awk可以讀取之前被截斷寫入。

我建議這樣做:

(
    mpc search artist 'Black Coast' && 
    mpc search artist 'ASTR' && 
    ls ~/music/HDD/Chill | awk '$0="HDD/Chill/"$0' 
) | awk '!v[$0]++' | tee testi.txt 

這樣,輸出文件只觸摸一次。

而且,我真的不喜歡的ls線的樣子 - 我建議使用這樣的事情:

(cd ~/music && printf '%s\n' HDD/Chill/*) 

這將創建一個額外的子shell,但不需要外部之一,所以您可以將您的命令改成這樣:

{ 
    mpc search artist 'Black Coast' && 
    mpc search artist 'ASTR' && 
    (cd ~/music && printf '%s\n' HDD/Chill/*) 
} | awk '!v[$0]++' | tee testi.txt 

,如果你的文件名包含換行符這將失敗(但話又說回來,這樣將原來的方法)。

+0

除了更容易複製(incase我想要更多文件夾),還有其他好處嗎? – RusinaRange

+0

我並不確定你的意思是更容易複製,但我想你是在問我使用'printf'。首先,避免在腳本中使用'ls'是一個好主意 - 在這種情況下,這不是什麼大問題,但是這是一個不好的習慣。這種方式也避免了重複的目錄名稱。 –

+0

我更容易複製的意思是重複目錄名稱。我並不是所有人都在意使用ls,但爲了避免重複,我會轉而使用它,並且整體看起來更乾淨。 – RusinaRange