我制作了一个shell脚本,我可以使用我的播放列表来制作MPD。我按照我想要的方式按文件夹和艺术家来编写歌曲,但是当我尝试使用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
所以我问问题改为为什么上面的例子不起作用?
答案 0 :(得分:0)
您正在写入您正在阅读的同一个文件。永远不要这样做,因为shell在阅读它之前可以写它。你想要这样的SOMETHING(未经测试):
(awk '!v[$0]++' testi.txt | tee tmp.txt) && mv tmp.txt testi.txt
答案 1 :(得分: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,但不需要外部子shell,因此您可以将命令更改为:
{
mpc search artist 'Black Coast' &&
mpc search artist 'ASTR' &&
( cd ~/music && printf '%s\n' HDD/Chill/* )
} | awk '!v[$0]++' | tee testi.txt
如果您的文件名包含换行符,则会失败(但是,您的原始方法也会如此)。