问题1

问题1

假设我有十个 bash shell 脚本:script1.sh, script2.sh, ..., script10.sh。最初,所有十个文件都是相同的。

现在,我想在每个脚本中进行两处更改:

  1. 在每个文件中,我想更改特定行(例如第 8 行)——也就是说,删除第 8 行上的所有内容并将其替换为“持续的”我指定的字符串,例如"This is line 8." 这类似于这个问题,但他们想用 替换"AAA""BBB"而我想用 替换第 8 行(无论它是什么)"This is line 8."

  2. 在每个文件中,我想更改另一个特定行(例如第 21 行)并将其替换为“多变的”我指定的字符串。例如,script1.sh我想将第 21 行更改为"XYZ";我script2.sh想将第 21 行更改为"PQR";我script3.sh想将第 21 行更改为"ABC".本质上,这只是对函数的多次调用(1)如上所述——除了我将在一个单独的文件而不是所有文件中进行更改,并且我指定十个不同的字符串而不仅仅是一个。所以要得到(2)在这里,也许我会打电话(1)十个不同的时间,不同的参数。

bash我对使用常用 Linux 程序(如、viawkgawk等)的解决方案感兴趣。

答案1

for file in f1 f2; do
  sed -i '8s/^.*$/foo/' "$file"
done

答案2

使用 awk

for file in script1.sh script2.sh script3.sh ... script10.sh; do
    temp=$(mktemp)
    awk '
        BEGIN {
            line8 = "This is line 8"
            line21["script1.sh"] = "XYZ"
            line21["script2.sh"] = "PQR"
            line21["script3.sh"] = "ABC"
            # ... 
        }
        FNR == 8 { print line8; next }
        FNR == 21 && FILENAME in line21 { print line21[FILENAME]; next }
        {print}
    '  "$file" > "$temp" && mv "$temp" "$file"
done

或者,使用 bash 和 sed

# bash variables to store new values. requires bash v4 for the associative array
line8="This is line 8"
declare -A line21=(
    [script1.sh]="XYZ"
    [script2.sh]="PQR"
    [script3.sh]="ABC"
    # ...
)
# then use sed
for file in script1.sh script2.sh script3.sh ... script10.sh; do
    sed -i "8s/.*/$line8/; 21s/.*/${line21[$file]}/" "$file"
done

使用 sed 解决方案,您必须小心新行不包含“/”字符,因为这会破坏命令s///。尽管您可以使用不同的分隔符,例如s|pattern|replacement|(在这种情况下,递归地应用相同的警告)

ed也有效:

for file in script1.sh script2.sh script3.sh ... script10.sh; do
    ed "$file" <<ED_COMMANDS
8d
8i
$line8
.
21d
21i
${line21[$file]}
.
w
q
ED_COMMANDS
done

答案3

我将回答这两个问题,但作为一般规则,请不要合并这样的问题,而是将它们分成单独的帖子。

问题1

  1. 珀尔:

    for f in *.sh; do 
      perl -i -lne '$.==8 ? print "This is line 8" : print;' "$f"; 
    done
    
  2. awk 及其变体:

    for f in *.sh; do 
      awk '{if(NR==8){print "This is line 8"}else{print}}' "$f" > fifo && 
      mv fifo "$f";
    done
    

问题2

我首先会创建一个文件,其中包含我想要进行的替换。例如:

script1.sh  foo1
script2.sh  foo2
script3.sh  foo3
script4.sh  foo4

然后读取该文件以执行替换:

while read f s; do 
 export s;
 perl -i -lne '$.==8 ? print "$ENV{s}" : print;' "$f";
done < sublist.txt

相关内容