求助:用sed和cut替换文件行第10位的1为3,脚本运行失败
如何替换文本文件中指定位置的数字?
我需要把存储的文本文件中各行第10位置的数字1替换为3,但尝试的脚本无法正常运行。以下是我的相关信息:
示例输入文件 (testdata.txt)
$ cat testdata.txt 1 43515 8 1 victor Samuel 20190112 3215736 4 6 Michael pristine 20180923 1 56261 1 1 John Carter 19880712
我尝试的脚本
#!/bin/sh filename=testdata.txt echo "reading number of line" nol=$(cat $filename | wc -l) flag[$nol]='' echo "reading content of file" for i in (1..$nol) do flag=($cut -c10-11 $filename) if($flag==1) sed 's/1/3/2' fi done
期望输出
1 43515 8 1 victor Samuel 20190112 3215736 4 6 Michael pristine 20180923 1 56261 3 1 John Carter 19880712
先分析你原脚本的问题
你的脚本存在多个Shell语法错误,导致无法运行:
for i in (1..$nol)是错误写法,Shell中生成数字序列应该用for i in $(seq 1 $nol)或者for ((i=1; i<=nol; i++))flag=($cut -c10-11 $filename)语法错误,执行命令并赋值要使用反引号或$(),而且这会把所有行的第10-11字符都赋值给数组,不是当前行的内容if($flag==1)语法错误,Shell的if判断格式应为if [ "$flag" = "1" ],且你这里的flag值逻辑也不正确sed 's/1/3/2'没有指定处理的目标行,也未关联当前行,无法精准修改指定位置
正确的解决方案
其实不需要写复杂的逐行循环,用sed或awk就能高效完成,它们天生擅长文本的位置匹配操作:
方法1:使用sed(推荐)
sed可以直接匹配指定位置的字符并替换:
sed 's/^\(.\{9\}\)1/\13/' testdata.txt
解释:
^匹配行开头\(.\{9\}\)捕获前9个任意字符,用\1保存这个结果1匹配第10个位置的数字1\13将前9个字符保留,把第10位的1替换为3
如果需要直接修改原文件(原地编辑),可以加-i参数:
sed -i 's/^\(.\{9\}\)1/\13/' testdata.txt
方法2:使用awk
awk也能按字符位置处理文本:
awk '{if (substr($0,10,1) == "1") $0 = substr($0,1,9) "3" substr($0,11); print}' testdata.txt
解释:
substr($0,10,1)获取当前行第10个字符- 如果该字符是1,就把行拼接为:前9个字符 + 3 + 第11位及之后的剩余内容
- 最后打印修改后的行
验证结果
运行上述任意命令后,输出都会和你期望的结果一致:
1 43515 8 1 victor Samuel 20190112 3215736 4 6 Michael pristine 20180923 1 56261 3 1 John Carter 19880712
内容的提问来源于stack exchange,提问作者Vikhyat Srivastava
相关产品推荐
相关产品推荐

