4

我有一个文件名列表,我想在第一个实例之前删除所有字符-。因此,Before: 列表中的以下名称显示为 After: 列表中的名称。

Before:
Adam James - Welcome Home.txt
Mike & Harry - One Upon - A Time.txt
William-Kent - Prince & The Frog.txt

After:
Welcome Home.txt
One Upon - A Time.txt
Prince & The Frog.txt

我一直在玩 sed 几个小时但无济于事。

我发现sed 's/ - .*//'在第一个实例之后删除了所有字符,-但之前我找不到相同的字符。

4

8 回答 8

5
$ awk '{print substr($0,index($0," - ")+3)}' file
Welcome Home.txt
One Upon - A Time.txt
Prince & The Frog.txt

i.e. just print from the end of the first occurrence of " - " to the end of the line.

于 2013-04-24T20:30:55.240 回答
4

像这样。

sed 's/^[^-]* - //'

许多正则表达式引擎允许*?非贪婪搜索,但 sed 不允许。

编辑:这不会改变 William-Kent 示例,嵌入的连字符会阻止匹配。

(此外,Perl 提供了一个非常方便的rename脚本来使用正则表达式批量重命名文件,但并非每个发行版都安装它。)

于 2013-04-24T20:12:58.727 回答
3

Simplest approach is too use grep:

$ grep -Po ' - \K.*' file
Welcome Home.txt
One Upon - A Time.txt
Prince & The Frog.txt
于 2013-04-24T20:30:03.823 回答
3

使用 awk 你可以:

awk 'BEGIN{FS=OFS="- "} NF>1{$1="";sub(/^- */, "")}'1 inFIle

现场演示:http: //ideone.com/2tBU4v

于 2013-04-24T20:15:28.913 回答
2

这可以在没有 bash 功能的普通 POSIX sh 中完成:

$ cat the_file_names 
Adam James - Welcome Home.txt
Mike & Harry - One Upon - A Time.txt
William-Kent - Prince & The Frog.txt

$ { while read FN; do echo ${FN#* - }; done; } < /tmp/the_file_names 
Welcome Home.txt
One Upon - A Time.txt
Prince & The Frog.txt

$ 
于 2013-04-24T21:08:30.567 回答
2

在纯 Bash 中(没有产生额外的子进程):

list=('Adam James - Welcome Home.txt' 'Mike & Harry - One Upon - A Time.txt')
for str in "${list[@]}"; do echo ${str#*-}; done

印刷:

Welcome Home.txt
One Upon - A Time.txt
于 2013-04-24T20:27:31.993 回答
1

这可能对您有用(GNU sed):

 sed 's/ - /\n/;s/.*\n//' file
于 2013-04-25T06:22:29.747 回答
1

我认为gawk这份工作可能更容易。

的使用FPAT可以简化问题:

awk -v FPAT="- .*$" 'sub(/^- /,"",$1)' file

使用您的数据:

kent$  echo "Adam James - Welcome Home.txt
Mike & Harry - One Upon - A Time.txt
William-Kent - Prince & The Frog.txt"|awk -v FPAT="- .*$" 'sub(/^- /,"",$1)'
Welcome Home.txt
One Upon - A Time.txt
Prince & The Frog.txt
于 2013-04-24T20:26:18.000 回答