使用 sed 在 bash for 循环中查找和替换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7974779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:01:20  来源:igfitidea点击:

using sed to find and replace in bash for loop

bashsed

提问by James Zaghini

I have a large number of words in a text file to replace.

我在文本文件中有大量要替换的单词。

This script is working up until the sed command where I get:

这个脚本一直运行到我得到的 sed 命令:

sed: 1: "*.js": invalid command code *

sed: 1: "*.js": 命令代码无效 *

PS... Bash isn't one of my strong points - this doesn't need to be pretty or efficient

PS... Bash 不是我的强项之一 - 这不需要漂亮或高效

cd '/Users/xxxxxx/Sites/xxxxxx'
    echo `pwd`;

    for line in `cat myFile.txt`
    do
        export IFS=":"
        i=0
        list=()

        for word in $line; do
            list[$i]=$word
            i=$[i+1]
        done

        echo ${list[0]}
        echo ${list[1]}

        sed -i "s/{$list[0]}/{$list[1]}/g" *.js

    done

采纳答案by Ignacio Vazquez-Abrams

You're running BSD sed (under OS X), therefore the -iflag requires an argument specifying what you want the suffix to be.

您正在运行 BSD sed(在 OS X 下),因此该-i标志需要一个参数来指定您想要的后缀。

Also, no files match the glob *.js.

此外,没有文件与 glob 匹配*.js

回答by Johnsyweb

This looks like a simple typo:

这看起来像一个简单的错字:

sed -i "s/{$list[0]}/{$list[1]}/g" *.js

Should be:

应该:

sed -i "s/${list[0]}/${list[1]}/g" *.js

(just like the echolines above)

(就像echo上面的几行一样)

回答by tripleee

So myFile.txtcontains a list of from:to substitutions, and you are looping over each of those. Why don't you create a sedscript from this file instead?

SomyFile.txt包含一个 from:to 替换列表,并且您正在遍历每个替换。为什么不sed从这个文件创建一个脚本呢?

cd '/Users/xxxxxx/Sites/xxxxxx'
sed -e 's/^/s:/' -e 's/$/:/' myFile.txt |
# Output from first sed script is a sed script!
# It contains substitutions like this:
# s:from:to:
# s:other:substitute:
sed -f - -i~ *.js

Your sedmight not like the -f -which means sedshould read its script from standard input. If that is the case, perhaps you can create a temporary script like this instead;

sed可能不喜欢-f -这意味着sed应该从标准输入读取其脚本。如果是这种情况,也许您可​​以创建一个这样的临时脚本;

sed -e 's/^/s:/' -e 's/$/:/' myFile.txt >script.sed
sed -f script.sed -i~ *.js

回答by javiunzu

Another approach, if you don't feel very confident with sed and think you are going to forget in a week what the meaning of that voodoo symbols is, could be using IFS in a more efficient way:

另一种方法,如果您对 sed 不是很自信,并认为您会在一周内忘记那个伏都教符号的含义,那么可以以更有效的方式使用 IFS:

IFS=":"
cat myFile.txt | while read PATTERN REPLACEMENT  # You feed the while loop with stdout lines and read fields separated by ":"
do
   sed -i "s/${PATTERN}/${REPLACEMENT}/g"
done

The only pitfall I can see (it may be more) is that if whether PATTERN or REPLACEMENT contain a slash (/) they are going to destroy your sed expression. You can change the sed separator with a non-printable character and you should be safe. Anyway, if you know whats on your myFile.txt you can just use any.

我能看到的唯一陷阱(可能更多)是,如果 PATTERN 或 REPLACEMENT 包含斜杠 (/),它们将破坏您的 sed 表达式。您可以使用不可打印的字符更改 sed 分隔符,您应该是安全的。无论如何,如果您知道 myFile.txt 上的内容,则可以使用任何内容。