Arr*_*cal 4 command-line bash sed text-processing
我有一个具有以下格式的文件:
A 485C72F95C72E15C EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
Run Code Online (Sandbox Code Playgroud)
我想使用变量“字母”的值提供第一列中的字母,并将第二列中的值替换为我在变量“id”中提供的值。在任何情况下,第三列可能不同或不匹配。第一列和第二列永远不会包含空格或特殊字符。
我尝试使用sed,但我的 sed-fu 不强。我想出了这个:
letter=A
id=MYNEWIDSTRING
sed "/$letter /s/[^ ]*/$id/2"
Run Code Online (Sandbox Code Playgroud)
输出是:
A MYNEWIDSTRING EXTERNAL
B MYNEWIDSTRING SYSTEM
C EC2A63F12A63B76C EXTERNAL
Run Code Online (Sandbox Code Playgroud)
id 被替换为两行,我假设这是由于在原始 id 字符串的末尾匹配了 'A '。
我知道用来sed -i就地编辑文件,但还没有这样做,因为我的命令仍然有点狡猾。
我哪里出错了,还是应该使用不同的方法?
锚定它(^是行首),以便A只有在它是第一个字符时才匹配:
$ letter=A; id=MYNEWIDSTRING; sed "/^$letter /s/[^ ]*/$id/2" file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您想将变量传递给sed但需要强引用,请记住,您可以在为变量添加双引号的同时打开和关闭引用 - 丑陋但通常可能是最佳实践:
sed '/^'"$letter"' /s/[^ ]*/'"$id"'/2'
Run Code Online (Sandbox Code Playgroud)
每当您处理结构化数据时,我都会使用awk或perl而不是sed.
例如
awk -v letter="A" -v id="MYNEWIDSTRING" '$1 == letter {$2=id}1' file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
Run Code Online (Sandbox Code Playgroud)
或者
perl -alne '
BEGIN{$letter = shift; $id = shift;}
print join " ", $F[0], $F[0] eq $letter ? $id : $F[1], @F[2..$#F]
' 'A' 'MYNEWIDSTRING' file
Run Code Online (Sandbox Code Playgroud)
较新版本的 GNU awk 有一个-i( --in-place) 标志;在其他情况下,您需要使用明确的临时文件;-i无论如何,perl 应该有一个。
| 归档时间: |
|
| 查看次数: |
5384 次 |
| 最近记录: |