我正在写一个小bash
脚本来工作。但现在我被卡住了。让我告诉你代码并解释一下:
# I have an `array` with names
NAMES=(Skypper Lampart Shepard Ryan Dean Jensen)
现在我想通过名字
进行迭代for (( i = 0; i < 6; i++ )); do
COMMAND="sed -i ${i+2}s/.*/${NAMES[${i}]}"
${COMMAND} config.txt
done
config.txt
是一个包含2个数字和名字的文件,我只想替换名称。
1
2
Name 1
Name 2
Name 3
Name 4
Name 5
Name 6
我的问题出在for
- 循环中如何制作$i
+ 2?因此,如果我$i
为1则应为3。
预期产出:
1
2
Skypper
Lampart
Shepard
Ryan
Dean
Jensen
答案 0 :(得分:1)
Bash擅长阅读数组(你可以轻松搜索的内容)。
尝试类似:
for idx in "${!NAMES[@]}"
do
sed -i "$((idx + 2))s/.*/${NAMES[idx]} $idx/" config.txt
done
除非你知道自己在做什么,否则你会发现在变量中放置命令也会失效,所以只需按预期使用命令:)
您可能还需要记住索引从零开始而不是1
答案 1 :(得分:1)
如果我理解你想要完成什么(用NAMES数组中的字符串替换“Name”,数组中索引的问题从0开始,你想从第3行开始) - 脏和快速的解决方案是添加2将字符串清空到数组的开头,然后从你想要的位置开始循环。
答案 2 :(得分:1)
使用此:
NAMES=(Skypper Lampart Shepard Ryan Dean Jensen)
line=2 # Need to skip first 2 lines
for name in "${NAMES[@]}"
do
((line++))
sed -i "${line}s/.*/$name/g" config.txt
done
答案 3 :(得分:1)
你可以尝试这样的事情:
NAMES=(Skypper Lampart Shepard Ryan Dean Jensen)
for (( i = 0; i < 6; i++ )); do
b=$(( $i+2 ))
COMMAND="sed -i $b s/.*/${NAMES[${i}]}"
echo $COMMAND
# ${COMMAND} config.txt
done
这给了我类似以下输出的内容:
# sh test.sh
sed -i 2 s/.*/Skypper
sed -i 3 s/.*/Lampart
sed -i 4 s/.*/Shepard
sed -i 5 s/.*/Ryan
sed -i 6 s/.*/Dean
sed -i 7 s/.*/Jensen
答案 4 :(得分:1)
有点迟到的答案......:)
在您的代码中,您呼叫sed
n次。这是低效的。因此,我提出了不同的解决方案,使用ed
代替sed
。 (正如30年前在BSD 2.9中的美好时光:) :)。
为此,方法:
ed
# it is good practice not using UPPERCASE variables
# as theycould collide with ENV variables
names=(Skypper Lampart Shepard Ryan Dean Jensen)
file="config.txt"
#create an array of commands for the "ed"
declare -a cmd
for name in "${names[@]}"; do
cmd+=("/Name/s//$name/")
done
cmd+=(w q)
echo "=== [$file before] ==="
cat "$file"
echo "=== [commands for execution ]==="
printf "%s\n" "${cmd[@]}"
#execute the prepared command in the "ed"
printf "%s\n" "${cmd[@]}" | ed -s "$file"
echo "===[ $file after ]==="
cat "$file"
从上面输出
=== [config.txt before] ===
1
2
Name 1
Name 2
Name 3
Name 4
Name 5
Name 6
=== [commands for execution ]===
/Name/s//Skypper/
/Name/s//Lampart/
/Name/s//Shepard/
/Name/s//Ryan/
/Name/s//Dean/
/Name/s//Jensen/
w
q
===[ config.txt after ]===
1
2
Skypper 1
Lampart 2
Shepard 3
Ryan 4
Dean 5
Jensen 6
替换为行号
的变体names=(Skypper Lampart Shepard Ryan Dean Jensen)
file="config.txt"
#create an array of commands for the "ed"
declare -a cmd
n=3
for name in "${names[@]}"; do
cmd+=("${n}s/.*/$name/")
let n++
done
cmd+=(w q)
echo "=== [$file before] ==="
cat "$file"
echo "=== [commands for execution ]==="
printf "%s\n" "${cmd[@]}"
#execute the prepared command in the "ed"
printf "%s\n" "${cmd[@]}" | ed -s "$file"
echo "===[ $file after ]==="
cat "$file"
输出
=== [config.txt before] ===
1
2
Name 1
Name 2
Name 3
Name 4
Name 5
Name 6
=== [commands for execution ]===
3s/.*/Skypper/
4s/.*/Lampart/
5s/.*/Shepard/
6s/.*/Ryan/
7s/.*/Dean/
8s/.*/Jensen/
w
q
===[ config.txt after ]===
1
2
Skypper
Lampart
Shepard
Ryan
Dean
Jensen