用 bash 中的另一个数字替换一个数字
Replace a digit with another digit in bash
我正在编写一个 bash 脚本,其中我想用 92 替换第一个数字 if 0 并且如果没有 0 和 92 在该数字前面附加 92 并将其保存在一个新文件中.
如有任何帮助,我们将不胜感激。
下面是我的 bash 脚本:
scrap.sh
#!/bin/bash
file=test.txt
while IFS=, read -r field1
do
echo $field1 | awk '[=11=]*=1'>> test2.txt
done < $file
test.txt
03333333333
3848123249
预期输出
923333333333
923848123249
使用您显示的示例,请尝试以下 awk
代码。
awk '{[=10=]=substr([=10=],1,1)==0?"92" substr([=10=],2):"92" [=10=]} 1' Input_file
解释: 简单的解释就是,使用awk
的substr
函数获取子字符串从当前行。在 awk
re-assigning 的主程序中,根据条件将值设为当前行 ([=15=]
)。如果第一个字符是 0
,则检查条件,然后将 [=15=]
值设置为 92
,第二个字符的其余行 ELSE 在 [=15=]
之前添加 92。最后提到 1
将打印当前 edited/non-edited 行。
假设这是您的输入文件:
cat file
03333333333
92123456789
3848123249
你可以使用这个 sed
:
sed -E '/^92/!s/0|^/92/' file
923333333333
92123456789
923848123249
sed
命令详情:
/^92/!
对不以 92
开头的行执行此操作
/0|^/
:匹配第一个0或一行的开始位置
/92/
:在起始位置 替换为92
等效的 awk
将是:
awk '!/^92/ {sub(/0|^/, "92")} 1' file
仅 bash 参数扩展:
$ while IFS= read -r line; do printf '92%s\n' "${line#0}"; done < test.txt
923333333333
923848123249
${line#0}
仅在前导零存在时删除它。
https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
我更喜欢带有安全检查的解决方案:
- (已确认在
gawk 5.11
+ mawk 1.3.4
+ mawk 1.9.9.6
+
macOS nawk
)
[nmg]awk '(/[1-9]/)*sub("^0?",92)'
原因是,上面提到的 awk '!/^92/ {sub(/0|^/, "92")} 1'
之类的解决方案会导致额外的空行以及只有零的行得到 92(除非这是预期的效果))
即
03333333333
3848123249
0
变成
923333333333
923848123249
92
92
如果你想 trim 去掉 所有前导零 (而不是其中的 1 个,并且只想要带有 non-zero 数字的行,并且不要根本不关心 nawk
,那就更简单了:
mawk2 '/[1-9]/*sub("^0*",92)'
or
mawk2 '(1<NF)*sub("^0*",92)' FS='[1-9]'
我正在编写一个 bash 脚本,其中我想用 92 替换第一个数字 if 0 并且如果没有 0 和 92 在该数字前面附加 92 并将其保存在一个新文件中.
如有任何帮助,我们将不胜感激。
下面是我的 bash 脚本:
scrap.sh
#!/bin/bash
file=test.txt
while IFS=, read -r field1
do
echo $field1 | awk '[=11=]*=1'>> test2.txt
done < $file
test.txt
03333333333
3848123249
预期输出
923333333333
923848123249
使用您显示的示例,请尝试以下 awk
代码。
awk '{[=10=]=substr([=10=],1,1)==0?"92" substr([=10=],2):"92" [=10=]} 1' Input_file
解释: 简单的解释就是,使用awk
的substr
函数获取子字符串从当前行。在 awk
re-assigning 的主程序中,根据条件将值设为当前行 ([=15=]
)。如果第一个字符是 0
,则检查条件,然后将 [=15=]
值设置为 92
,第二个字符的其余行 ELSE 在 [=15=]
之前添加 92。最后提到 1
将打印当前 edited/non-edited 行。
假设这是您的输入文件:
cat file
03333333333
92123456789
3848123249
你可以使用这个 sed
:
sed -E '/^92/!s/0|^/92/' file
923333333333
92123456789
923848123249
sed
命令详情:
/^92/!
对不以92
开头的行执行此操作
/0|^/
:匹配第一个0或一行的开始位置/92/
:在起始位置 替换为
92
等效的 awk
将是:
awk '!/^92/ {sub(/0|^/, "92")} 1' file
仅 bash 参数扩展:
$ while IFS= read -r line; do printf '92%s\n' "${line#0}"; done < test.txt
923333333333
923848123249
${line#0}
仅在前导零存在时删除它。
https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
我更喜欢带有安全检查的解决方案:
- (已确认在
gawk 5.11
+mawk 1.3.4
+mawk 1.9.9.6
+ macOSnawk
)
[nmg]awk '(/[1-9]/)*sub("^0?",92)'
原因是,上面提到的 awk '!/^92/ {sub(/0|^/, "92")} 1'
之类的解决方案会导致额外的空行以及只有零的行得到 92(除非这是预期的效果))
即
03333333333
3848123249
0
变成
923333333333
923848123249
92
92
如果你想 trim 去掉 所有前导零 (而不是其中的 1 个,并且只想要带有 non-zero 数字的行,并且不要根本不关心 nawk
,那就更简单了:
mawk2 '/[1-9]/*sub("^0*",92)'
or
mawk2 '(1<NF)*sub("^0*",92)' FS='[1-9]'