从文本文件中提取字符串,然后在bash中相应地重命名它们

时间:2019-03-15 22:57:45

标签: regex bash

我有很多随机命名的文本文件(大约70000个文件);我所知道的是,在前30行中的某处有两行格式为Author: Samuel Richardson,另一行为Title: Clarissa, Volume 5 (of 9)。我不确定这两行的情况。

我想提取标题和作者,并相应地重命名文件,类似于"Clarissa, Volume 5 (of 9) ,___, Samuel Richardson.txt"(我使用,___,,以便作者和标题之间有有效的分隔符。

我的代码是

for filename in *.txt; do

    title=$(head -n 30 $filename.txt | grep -i 'Title:' | sed -n 's/^.*Title: //p')
    author=$(head -n 30 $filename.txt | grep -i 'Author:' | sed -n 's/^.*Author: //p')
    new_name="$title ,___, $author"

    mv $filename $new_name.txt
done

它没有按预期工作。子代码

echo "title: $title _"
echo "author: $author _"

new_name="$title ,___, $author"

echo $new_name

将以下内容作为输出打印

 _tle: Clarissa, Volume 5 (of 9)
 _thor: Samuel Richardson
 ,___, Samuel Richardson)

此外,我不知道如何使用head命令将前30行提取的计算保存到变量firstlines中,因此不应重新计算。

代码

firstlines=$(head -n 30 randomname.txt)

title=$($firstlines | grep -i 'Title:' | sed -n 's/^.*Title: //p')

的使用

打印出错误command not found

2 个答案:

答案 0 :(得分:0)

@Poshi的权利:您的主要问题是行尾。看起来每行结尾都包含回车符(\r)。 \r本身仅将光标移回该行的开头。与\n结合使用时,它可以正常工作-因为它移到了 next 行的开头-但它本身会导致您看到的内容:一些文本,然后是光标回到该行的开头,然后是更多的文本覆盖原来的内容。

编辑:如果我提供了一个解决方案,可能会有所帮助。在分配给new_name之前插入这样的内容应该起作用:

title=$(echo -e $title | sed 's/\r//')
author=$(echo -e $author | sed 's/\r//')

关于第二个问题,得到command not found的原因是变量$firstlines中的第一个单词不是命令。您想要类似的东西:

title=$(echo -e $firstlines | grep -i 'Title:' | sed -n 's/^.*Title: //p')

答案 1 :(得分:0)

@Poshi关于行尾的评论是正确的,@ B.Shefter的答案是正确的,但存在许多问题(未引用变量引用,依赖于echo和{{1}的非标准功能) }),所以我认为我希望(希望)重写已解决的问题。

此外,我将重复我在评论中给出的建议:使用sedmv -n以避免出现任何问题而覆盖文件,并首先进行备份。 (无论如何,您都有备份,对吧?您应该始终备份任何您不想丢失的内容。)

无论如何,这是我的看法:

mv -i