将sed输出传递给mv

时间:2014-06-15 07:29:01

标签: regex bash sed

我正在尝试根据它们包含的字符串批量重命名文本文件 我使用sed将模式与\(和\)隔离,因为我无法在grep中使用它。

sed -i '' 's/<title>\(.*\)<\/title>/&/g' *.txt | mv *.txt $sed.txt

(我想用作文件名的文本在html标题标签之间)`
我写的地方$ sed将是sed的输出。

希望这很清楚!

4 个答案:

答案 0 :(得分:1)

bash中的一个简单循环可以实现这一点。如果每个文件都是有效的HTML,意味着文件中只有一个<title>标记,则可以这样重命名:

for file in *.txt; do 
    mv "$file" `sed -n  's/<title>\([^<]*\)<\/title>/\1/p;' $file| sed -e 's/[ ][ ]*/_/g'`.txt
done

因此,如果您有文件1.txt2.txt3.txt,则每个文件的TITLE标记中都有catdogmy hippo在上述循环之后,您最终会得到cat.txtdog.txtmy_hippo.txt

编辑:引用初始$file,以防文件名中有空格;并添加了第二个sed,以便将<title>标记中的任何空格转换为生成的文件名中的_注意第二个[]命令中sed内的空格是文字spacetab字符。

答案 1 :(得分:0)

您可以将表达式括在严重重音字符(`)中,以使其输出到您想要的位置。尝试:

mv *.txt `sed -i '' 's/<title>\(.*\)<\/title>/&/g' *.txt`.txt

它不灵活,但应该有用。

(我暂时没有使用它,现在无法测试,所以我可能错了)。

答案 2 :(得分:0)

我从你的问题中读到的是:

  1. 目录中有许多文本(html)文件
  2. 每个文件至少包含标记<title> ... </title>
  3. 您要提取内容(elements.text)并将其用作文件名
  4. 最后要将该文件重命名为提取的文件名
  5. 这是对的吗?

    那么,你需要遍历文件,例如使用xargs或找到

    1. ls '*.txt' | xargs -i\{\} command "{}" ...
    2. find -maxdepth 1 -type f -name '*.txt' -exec command "{}" ... \;
    3. 我总是用-i\{\}替换xargs替换,因为如果我有时使用find和它的替换{},结果命令是兼容的。

      接下来-maxdepth选项将帮助您找到不深入目录,如果没有子目录,您可以将其删除。

      command可能非常简单,如echo "Testing File: {}"或非常小的脚本,如果你将它与bash一起使用:

      find . -name '*.txt' -exec bash -c 'CUR_FILE="{}"; echo "Working on: $CUR_FILE"; ls -l "$CUR_FILE";' \;

      您的问题的最大决定是:如何从title元素中获取文本。

      1. 一个简单的解决方案(如果打开和关闭标签位于同一文本行上,则适用)将由grep
      2. 提供
      3. 更可靠的解决方案是使用HTML Parser并按DOM操作导航
      4. 简单的解决方案基于:

        1. 获得标题行
        2. 删除标题内容之前和之后的所有内容
        3. 所以一起做:

          ls *.txt | xargs -i\{\} bash -c 'TITLE=$(egrep "<title>[^<]*</title>" "{}"); NEW_FNAME=$(echo "$TITLE" | sed -e "s#.*<title>\([^<]*\)</title>.*#\1#"); mv -v "{}" "$NEW_FNAME.txt"'

          与find:

          的用法相同

          find . -maxdepth 1 -type f -name '*.txt' -exec bash -c 'TITLE=$(egrep "<title>[^<]*</title>" "{}"); NEW_FNAME=$(echo "$TITLE" | sed -e "s#.*<title>\([^<]*\)</title>.*#\1#"); mv -v "{}" "$NEW_FNAME.txt"' \;

          希望这是你的期望。

答案 3 :(得分:0)

这是我要使用的命令:

for i in *.txt ; do
    sed "s=<title>\(.*\)</title>=mv '$i' '\1'=e" $i
done

sed替换搜索每个.txt文件中的模式。对于每个文件,它创建字符串mv 'file_name' 'found_pattern' 使用e命令末尾的sed命令,此结果字符串将直接在终端中执行,因此它会重命名您的文件。

一些提示:

  1. 请注意,使用=而不是/作为sed替换的分隔符:由于您已经拥有/ s,因此它更具可读性模式(如果你不喜欢=,你可以使用许多其他符号)。通过这种方式,您不必逃避模式中的/
  2. e的{​​{1}}命令执行创建的字符串 (我在下面谈到这个:

    sed


    所以要谨慎使用!我建议首先使用没有最终sed "s=<title>\(.*\)</title>=mv '$i' '\1'=e" $i ^ 的行:它不会执行任何e命令,而只是打印而不是执行添加mv