Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 编写shell脚本以替换文件中的电话号码_Bash - Fatal编程技术网

Bash 编写shell脚本以替换文件中的电话号码

Bash 编写shell脚本以替换文件中的电话号码,bash,Bash,我有一个名为test.txt的文件,该文件的内容是: abc,123456,印度 dfg,78910,中国 abc,893948,日本 澳大利亚广播公司,892389 我尝试过使用下shell脚本,但无法替换它 #!/bin/bash for line in $(cat /tmp/file.txt) do i=$(echo $line|grep XYZ |awk -F, '{print $2}') while ( $i ) do sed -i 's/$

我有一个名为test.txt的文件,该文件的内容是:

abc,123456,印度
dfg,78910,中国
abc,893948,日本
澳大利亚广播公司,892389
我尝试过使用下shell脚本,但无法替换它

#!/bin/bash

for line in $(cat /tmp/file.txt)
do
    i=$(echo $line|grep XYZ |awk -F, '{print $2}')
    while ( $i )
    do
        sed -i 's/$i/00070/g';
    done
done

您只是想让每行的第二列成为字符串“00070”吗?与其用while循环遍历文件,不如让
sed
迭代,因为它就是这样做的。例如
sed的/\([^,]*\),[^,]*,/\100070,/'
。但是
sed
是错误的工具,您只需执行以下操作:

awk '{$2="00070"}1' FS=, OFS=, /tmp/file.txt
编辑:在注释中指定特定性。要限制更换,只需执行以下操作:

awk '$1 ~ /abc/ {$2="00070"}1' FS=, OFS=, /tmp/file.txt

例如,您可以使用awk:

awk -F"," '{ print $1=="abc" ? $1",00070,"$3 : $0 }' test.txt
-F指定delimeter(逗号)

或者,如果需要将其替换为任何其他字符串:

#!/bin/sh
REPLACE=00070
if [ "$1" != '' ] ; then
    REPLACE=$1
fi

awk -F"," "{print (\$1==\"abc\" ? \$1\",$REPLACE,\"\$3 : \$0 }" test.txt
既然您说过“仅在bash中”,那么这里有一个简单化的全bash解决方案

$: while IFS=, read name number country
>  do case "$name" in
>     abc) echo "$name,00070,$country"   ;;
>       *) echo "$name,$number,$country" ;;
>     esac
>  done < infile
abc,00070,india
dfg,78910,china
abc,00070,japan
abc,00070,australia
根本不需要脚本

解释:

/^abc/
表示“对于以
abc
开头(
^
)的每个记录,请执行以下操作

s
声明用第二部分替换第一部分

,[^,]*,
(第一部分)说找到一个逗号,后跟任意数量的非逗号(
^
[…]
中表示“不是这些”),然后是另一个逗号

然后第二节说用一个literal
,00070,
替换我们在第一节中找到的内容

如果要将其作为脚本编写,可以传入触发器和替换字符串

 #! /usr/bin/bash
 sed "/^$1,/s/,[^,]*,/,$2,/" $3
然后运行它:

$: ./tst abc 00070 infile
abc,00070,india
dfg,78910,china
abc,00070,japan
abc,00070,australia

$: ./tst dfg 987654321 infile
abc,123456,india
dfg,987654321,china
abc,893948,japan
abc,892389,australia
然后,您可以开始添加诸如错误检查、值约束、带有
getopts
的非位置参数等内容……但这里有一个快速工作的模板



(如果要在目标文件中更改名称/编号的整个文件,请查找关联数组-不要将其作为嵌套循环,对另一个文件中的每个记录编辑整个文件一次。可以通过一次遍历来完成。)

您可以使用python@PaoloMossini这是在一次采访中被问到的,他们只在bash中需要它。这回答了你的问题吗?@dibery我已经用我的脚本编辑了这个问题,请检查,你删除了你想做的。这会让人们很难回答。如果每行的第二列有“abc”,我会尝试替换它“在第一列中,并非所有行您的脚本都将第二列的整行更改为00070,但只需要更改第一列为abc的行@user1208381这正是第二个awk所做的。它读取第一个字段是否匹配正则表达式
abc
$1~/abc/
),然后将第二个字段更新为“00070”(
$2=“00070”
)。打印所有记录(
1
)@user1208381如果我运行命令
$echo'abc,123456,india'| awk'$1~/abc/{$2=“00070”}1'FS=,OFS=,
它将返回我的输出
abc,00070,india
。如果您的情况不是这样,那么您应该知道您的输入可能有问题。内容在一个文件中,因此我尝试如下操作,但在读取行时无法工作
code
;doecho$line | awk'$1~/abc/{$2=“00070”}1'FS=,OFS=,;完成codeI试图替换每行的第二列,如果第一列中有“abc”,所有这些名称、编号,国家/地区在一个文件中,因此有没有任何方法可以将文件作为输入传递,就像它是拥抱文件一样,我们最终会传递参数很多次我是sed新手,请您解释一下sed'/^abc,/s/,[^,]*,/,00070,/'它是如何工作的?主要是在s/Code-only答案被认为是低质量的之后:确保提供一个解释,说明你的代码是做什么的,以及它是如何解决问题的。如果你能在你的文章中添加更多的信息,这将有助于询问者和未来的读者。另请参阅解释完全基于代码的答案:@borchvm内容在文件中,它有数千次出现,请告诉我一种迭代方式,输入必须是file@user1208381这是关于添加一个小的解释,解释为什么这个代码或文件片段可能是解决方案。这不仅对提出问题的用户很有用,而且对将来提出这个问题的用户也很有用。你能解释一下你是如何在这里使用awk的吗?再多提供一些信息会很有帮助。上面有一个很好的例子,@William Pursell解释得很好
$: ./tst abc 00070 infile
abc,00070,india
dfg,78910,china
abc,00070,japan
abc,00070,australia

$: ./tst dfg 987654321 infile
abc,123456,india
dfg,987654321,china
abc,893948,japan
abc,892389,australia
awk 'BEGIN{FS=OFS=","}!/dfg/{$2="00070"}1' file
abc,00070,india
dfg,78910,china
abc,00070,japan
abc,00070,australia