BASH echo与sed的用法

3
我有:
Location.txt(内容)
some_line1
some_line2
some_line3

区域.txt(内容)

region1
region2
region3

uri.txt (content)

/some_text/some_text1/***/
/some_text/***/some_text2/
/***/some_text/some_text3/

我需要创建文件。
region1
region2
region3

每个文件都需要填写以下内容(将地区的名称替换星号)

region1文件的示例

/some_text/some_text1/region1/
some_line1
some_line2
some_line3

/some_text/region1/some_text2
some_line1
some_line2
some_line3

/region1/some_text/some_text3
some_line1
some_line2
some_line3

文件区域2的示例(区域名称而非星号)

/some_text/some_text1/region2/
some_line1
some_line2
some_line3

/some_text/region2/some_text2
some_line1
some_line2
some_line3

/region2/some_text/some_text3
some_line1
some_line2
some_line3

现在我有。
#!/bin/bash

while read region
    do
        while read uri
        do
            echo $uri >> "/home/user/regions/$region"
        done < uri.txt
    done < region.txt

这个脚本会根据region.txt中的每行文本创建文件,并将其填充为来自uri.txt的文本行。但我需要创建很多这样的文件,每个文件应该包含很多位置,但每个位置中的一行应更改为来自uri.txt的另一行。看起来我需要使用:
cat $file|sed 's/^was/now/'

但我不知道如何使用它。

请帮忙。


1
“location.txt” 文件在哪里发挥作用?您在描述的开头列出了它,并在下一段中提到了它,但是您没有在任何其他地方引用它,因此不清楚您在所有“/home/user/regions/$region”文件中寻找什么内容。 - lurker
也许在其中一个文件中添加一些样本,并给出预期结果。 - NeronLeVelu
抱歉,我已经编辑了我的帖子。 - merlin.metso
4个回答

2
我会使用awk来处理这个问题:
awk -v loc="$(< Location.txt)" '
    NR==FNR {region[$1]=1;next}
    {for (reg in region) {
        sub(/\*\*\*/, reg)
        f = reg ".txt"
        print > f
        print loc > f
    }}
' region.txt uri.txt

谢谢你。但是对我来说太重了 :) - merlin.metso

2

@user2874004:您的脚本写得更好一些:

#!/bin/bash

mkdir -p configs # make directory for configs if it doesnt exist

while IFS= read -r reg # read next line from reg.txt
do
    while IFS= read -r uri # read next line from uri.txt
    do
        echo "    ${uri//\*\*\*/$reg} {" # make changes
        while IFS= read -r loc # read next line from location.txt
        do
            echo "        $loc" # fill in the location 
        done < location.txt
    done < uri.txt > "./config/$reg.txt"
done < region.txt

我不知道它具体是做什么的,尽管有一个笑脸符号:)


它使用数十个规则为数千个位置生成数千个包含文件。 - merlin.metso
谁知道NGINX配置是否正常? - merlin.metso

1
如果我理解你的问题正确,那么三个嵌套的for循环可以完成任务。
for reg in $(cat region.txt )
do
  echo -n > $reg.txt
    for uri in $(cat uri.txt )
    do
      echo "$uri" | sed -e "s/\*\*\*/$reg/g" | tee -a $reg.txt
        for loc in $(cat Location.txt )
        do
          echo $loc | tee -a $reg.txt
        done
    done
done

结果:

$ cat region1.txt 
/some_text/some_text1/region1/
some_line1
some_line2
some_line3
/some_text/region1/some_text2/
some_line1
some_line2
some_line3
/region1/some_text/some_text3/
some_line1
some_line2
some_line3

我希望这会有所帮助!

echo "$uri" | sed -e "s/***/$reg/g" | tee -a $reg.txt非常有用。谢谢你。 - merlin.metso
发现了糟糕的做法:在“cat”上使用“for”循环。为传播不良实践感到羞耻!“-1”。 - gniourf_gniourf
好的,谢谢。现在我明白了...不要依赖于单个空格分隔符,因为不能保证输入中没有空格... - csikos.balint

0
最终我使用了以下代码,它可以正常工作。
#!/bin/bash

mkdir -p configs # make directory for configs if it doesnt exist

while read reg # read next line from reg.txt
do
  if [ -f ./configs/$reg.txt ]; then # if file allready exist then 
    rm ./configs/$reg.txt # delete it
  fi
    while read  uri # read next line from uri.txt
    do
        echo "    $uri {" | sed -e "s/\*\*\*/$reg/g"  >> ./configs/$reg$ # make changes
        while read loc # read next line from location.txt
        do
                echo "        $loc" >> ./configs/$reg.txt # fill in the location 
        done < location.txt
    done < uri.txt
done < region.txt

感谢大家的帮助。


1
如果文件名中有空格,你的东西会出问题。使用更多引号!实际上,在你的脚本中有很多错误...太多了,我无法在评论中解释它们。 - gniourf_gniourf
谢谢您的评论。我是脚本的初学者,但我会不断进步 :) 文件名是由我创建的,所以不能有空格。您能解释一下为什么我应该使用更多引号吗? - merlin.metso
1
只要养成习惯,即使你确定文件名不包含空格,也始终使用引号。这是你可以养成的最好习惯:这样你就可以在不经意间编写出健壮的程序! - gniourf_gniourf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接