首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash:如何使用变量作为带有多组引号的参数

Bash:如何使用变量作为带有多组引号的参数
EN

Stack Overflow用户
提问于 2014-03-12 09:10:08
回答 2查看 567关注 0票数 0

我有一个装满了mp3s的文件夹,我想去掉所有id3用户文本帧(除了重放增益)--我编写的这段代码将完成它,但是它将循环遍历每个文件,为每个找到的标记,以删除它。这会导致脚本在每个mp3上循环多次以完成我想要的任务。

下面是工作的代码:

代码语言:javascript
复制
#!/usr/bin/env bash
userframes=`eyeD3 *.mp3 | grep UserTextFrame | grep -v replaygain | awk -F ":" '{print $3}' | sed 's/]//g' | sed -e 's/^[ \t]*//' | sed 's/\s*$//g' | sort | uniq`

SAVEIFS=$IFS
IFS=$'\n'
for f in $userframes; do
    eyeD3 --user-text-frame="$f:" *.mp3
done
IFS=$SAVEIFS

我希望提高效率,并对每个mp3使用变量中的每个条目一次,如下所示:

代码语言:javascript
复制
eyeD3 --user-text-frame="desc1:" --user-text-frame="desc2:" *.mp3

但我不知道该怎么做。我想我是通过尝试一次用变量中的开关绘制列表来接近的,但是有一些奇怪的字符转义问题我无法弄清楚。

代码语言:javascript
复制
eyeD3 *.mp3 | grep UserTextFrame | grep -v replaygain | awk -F ":" '{print $3}' | sed 's/]//g' | sed -e 's/^[ \t]*//' | sed 's/\s*$//g' | sort | uniq | sed -e "s|'|"'\\\'"'|g" | awk '{print "--user-text-frame=\x27" $0 ":\x27"}' | sed ':a;N;$!ba;s/\n/ /g'

它列出了这样一个列表(我尝试了双引号而不是单引号,并避免了双引号):

代码语言:javascript
复制
--user-text-frame='ALBUMARTISTSORT:' --user-text-frame='ASIN:' --user-text-frame='Album Artist Credit:' --user-text-frame='Artist Credit:' --user-text-frame='CATALOGNUMBER:' --user-text-frame='MusicBrainz Album Artist Id:' --user-text-frame='MusicBrainz Album Id:' --user-text-frame='MusicBrainz Album Release Country:' --user-text-frame='MusicBrainz Album Status:' --user-text-frame='MusicBrainz Album Type:' --user-text-frame='MusicBrainz Artist Id:' --user-text-frame='MusicBrainz Release Group Id:' --user-text-frame='Script:'

但是,我不能像这样成功地将它作为变量传递给eyeD3:

代码语言:javascript
复制
frames=`eyeD3 *.mp3 | grep UserTextFrame | grep -v replaygain | awk -F ":" '{print $3}' | sed 's/]//g' | sed -e 's/^[ \t]*//' | sed 's/\s*$//g' | sort | uniq | sed -e "s|'|"'\\\'"'|g" | awk '{print "--user-text-frame=\x27" $0 ":\x27"}' | sed ':a;N;$!ba;s/\n/ /g'`

eyeD3 $frames *.mp3

我要么犯了错误

"eyeD3:错误:不被认可的论点:信用:‘专辑Id:’专辑发行国家:‘专辑状态:’专辑类型:‘艺术家Id:’01 -做Joy.mp3 02 - Love.mp3 03 -所以光是她的Footfall.mp3 04 -是她的Footfall.mp3 04-是一个Bee.mp3 05 -错过了Day.mp3 06 -热带Disease.mp3 07 -天堂的Light.mp3 08 -夜Hunter.mp3 09 - Sing Sang Sung.mp3 10 -吃我的Beat.mp3 11 -你可以告诉Everybody.mp3 12 -非洲的Velvet.mp3“

或者,如果我尝试使用转义引号,我最终会在现有的标签之上添加更多的重复标记,比如

代码语言:javascript
复制
'tag
tag

在过去的地方

代码语言:javascript
复制
tag

也许有更简单的方法来做我想做的事?

编辑:

根据帮助,eyeD3命令的语法:

代码语言:javascript
复制
--user-text-frame DESC:TEXT
                    Set the value of a user text frame (i.e., TXXX). To
                    remove the frame, specify an empty value. e.g.,
                    --user-text-frame='SomeDesc:'

举个例子:

代码语言:javascript
复制
eyeD3 --user-text-frame='ALBUMARTISTSORT:' *.mp3

应该从目录中的所有mp3s中删除带有描述ALBUMARTISTSORT的用户文本框架标记。

使用一个文件从eyeD3发出的典型输出(输入*mp3只为dir中的所有mp3s生成多个条目)

代码语言:javascript
复制
$ eyeD3 12\ -\ African\ Velvet.mp3 
12 - African Velvet.mp3 [ 6.82 MB ]
-------------------------------------------------------------------------------
Time: 03:51 MPEG1, Layer III    [ ~247 kb/s @ 44100 Hz - Joint stereo ]
-------------------------------------------------------------------------------
ID3 v2.3:
title: African Velvet
artist: Air
album: Love 2
recording date: 2009
track: 12       genre: Electronic (id 52)
disc: 1/1
BPM: 0
Publisher/label: Emi
Unique File ID: [http://musicbrainz.org] : c5981690-b9ef-45f4-a8ce-7696a75190fb
Comment: [Description: ] [Lang: eng]

Lyrics: [Description: ] [Lang: eng]

UserTextFrame: [Description: replaygain_album_gain]
-9.11 dB
UserTextFrame: [Description: replaygain_album_peak]
1.238762
UserTextFrame: [Description: replaygain_track_gain]
-7.69 dB
UserTextFrame: [Description: replaygain_track_peak]
1.026620
UserTextFrame: [Description: CATALOGNUMBER]
509999663960-3
UserTextFrame: [Description: Album Artist Credit]
Air
UserTextFrame: [Description: MusicBrainz Album Type]
album
UserTextFrame: [Description: MusicBrainz Album Artist Id]
cb67438a-7f50-4f2b-a6f1-2bb2729fd538
UserTextFrame: [Description: MusicBrainz Artist Id]
cb67438a-7f50-4f2b-a6f1-2bb2729fd538
UserTextFrame: [Description: Script]
Latn
UserTextFrame: [Description: ASIN]
B002G9TWQQ
UserTextFrame: [Description: Artist Credit]
Air
UserTextFrame: [Description: ALBUMARTISTSORT]
Air
UserTextFrame: [Description: MusicBrainz Release Group Id]
34961bd0-b55b-4e9c-97eb-99763419afc0
UserTextFrame: [Description: MusicBrainz Album Id]
7e445cb0-3df7-3c38-b318-d68713294ff8
UserTextFrame: [Description: MusicBrainz Album Status]
Official
UserTextFrame: [Description: MusicBrainz Album Release Country]
CA
-------------------------------------------------------------------------------
EN

回答 2

Stack Overflow用户

发布于 2014-03-12 09:45:11

请在你的变量周围加上一对双引号。

代码语言:javascript
复制
eyeD3 "$frames" *.mp3
票数 0
EN

Stack Overflow用户

发布于 2014-03-12 19:27:25

我会用这样的方法

代码语言:javascript
复制
regex='UserTextFrame: [Description: (.*)]'
eyeD3 *.mp3 | grep UserTextFrame | grep -v replaygain | while read; do
    [[ $REPLY =~ $regex ]] && echo "${BASH_REMATCH[1]}"
done | sort -u | while read frame; do
    eyeD3 --user-text-frame "$frame:" *.mp3 
done

管道的前三个阶段和你的一样。接下来,我使用一个简单的while循环和正则表达式匹配来输出"Description“后面的文本,直到结束括号。这个while循环的输出由所有MP3s上的所有描述组成。这是通过管道通过sort -u消除重复,然后输入到另一个while循环中删除所有MP3s中的每个唯一项。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22346687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档