在 shell 脚本中使用 sed 命令获取子字符串并替换需要的位置
Using sed command in shell script for substring and replace position to need
我正在处理文本文件中的数据,我找不到使用 sed 的方法 select 固定位置的子字符串并替换它。
这是我的:
X|001200000000000000000098765432|1234567890|TQ
这是我需要的:
‘X’,’00000098765432’,’1234567890’,’TQ’
sed 中的以下代码给出了我需要的子字符串 (00000098765432) 但没有覆盖需要的位置
echo “ X|001200000000000000000098765432|1234567890|TQ” | sed “s/
*//g;s/|/‘,’/g;s/^/‘/;s/$/‘/“
你能帮帮我吗?
我会用 awk
而不是 sed
。
echo "X|001200000000000000000098765432|1234567890|TQ" | awk 'BEGIN {FS="|";OFS=","} {print ,substr(,17,14),,}'
给出输出:
X,00000098765432,1234567890,TQ
这是它的工作原理:
FS
= 字段分隔符(在输入中)
OFS
= 输出字段分隔符(您希望输出分隔的方式)
BEGIN
-> 将其视为设置配置的地方。它只运行一次。所以你是说你希望输出以逗号分隔,输入以竖线分隔。
substr(,17,14)
-> 取 $2(即第二个字段 - awk 从 1 开始计数 - 然后在其上应用子字符串。17 表示起始字符位置,14 表示从该位置开始的字符数)
在我看来,这比您拥有的 sed 版本更具可读性和可维护性。
如果要加引号,我还是用awk
。
$: awk -F'|' 'BEGIN{q="7"} {print q q","q substr(,17,14) q","q q","q q"\n"}' <<< "X|001200000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'
如果你只是想用sed
,注意你上面说要去掉16个字符,但实际上你只去掉了14个。
$: sed -E "s/^(.)[|].{14}([^|]+)[|]([^|]+)[|]([^|]+)/'','','',''/" <<< "X|0012000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'
使用sed
$ sed "s/|\(0[0-9]\{15\}\)\?/','/g;s/^\|$/'/g" input_file
'X','00000098765432','1234567890','TQ'
awk -v del1="7" \
-v del2="," \
-v start="3" \
-v len="17" \
'{
gsub(substr([=10=],start+1,len),"");
gsub(/[\|]/,del1 del2 del1);
print del1[=10=]del1
}' input_file
'X',00000098765432','1234567890','TQ'
使用任何 POSIX awk:
$ echo 'X|001200000000000000000098765432|1234567890|TQ' |
awk -F'|' -v OFS="','" -v q="'" '{sub(/.{16}/,"",); print q [=10=] q}'
'X','00000098765432','1234567890','TQ'
没有我希望的那么优雅,但它完成了工作:
'X','00000098765432','1234567890','TQ'
# gawk profile, created Mon May 9 21:19:17 2022
# BEGIN rule(s)
'BEGIN {
1 _ = sprintf("%*s", (__ = +2)^++__+--__*++__,__--)
1 gsub(".", "[0-9]", _)
1 sub("$", "$", _)
1 FS = "[|]"
1 OFS = ","
}
# Rule(s)
1 (NF *= NF == __*__) * sub(_, "|&", $__) * \
sub("^.*[|]", "", $__) * sub(".+", "&") }'
已在 gnu gawk 5.1.1
、mawk 1.3.4
、mawk 1.9.9.6
和 macosx nawk
上进行测试和确认
—The 4Chan Teller
我正在处理文本文件中的数据,我找不到使用 sed 的方法 select 固定位置的子字符串并替换它。
这是我的:
X|001200000000000000000098765432|1234567890|TQ
这是我需要的:
‘X’,’00000098765432’,’1234567890’,’TQ’
sed 中的以下代码给出了我需要的子字符串 (00000098765432) 但没有覆盖需要的位置
echo “ X|001200000000000000000098765432|1234567890|TQ” | sed “s/
*//g;s/|/‘,’/g;s/^/‘/;s/$/‘/“
你能帮帮我吗?
我会用 awk
而不是 sed
。
echo "X|001200000000000000000098765432|1234567890|TQ" | awk 'BEGIN {FS="|";OFS=","} {print ,substr(,17,14),,}'
给出输出:
X,00000098765432,1234567890,TQ
这是它的工作原理:
FS
= 字段分隔符(在输入中)
OFS
= 输出字段分隔符(您希望输出分隔的方式)
BEGIN
-> 将其视为设置配置的地方。它只运行一次。所以你是说你希望输出以逗号分隔,输入以竖线分隔。
substr(,17,14)
-> 取 $2(即第二个字段 - awk 从 1 开始计数 - 然后在其上应用子字符串。17 表示起始字符位置,14 表示从该位置开始的字符数)
在我看来,这比您拥有的 sed 版本更具可读性和可维护性。
如果要加引号,我还是用awk
。
$: awk -F'|' 'BEGIN{q="7"} {print q q","q substr(,17,14) q","q q","q q"\n"}' <<< "X|001200000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'
如果你只是想用sed
,注意你上面说要去掉16个字符,但实际上你只去掉了14个。
$: sed -E "s/^(.)[|].{14}([^|]+)[|]([^|]+)[|]([^|]+)/'','','',''/" <<< "X|0012000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'
使用sed
$ sed "s/|\(0[0-9]\{15\}\)\?/','/g;s/^\|$/'/g" input_file
'X','00000098765432','1234567890','TQ'
awk -v del1="7" \
-v del2="," \
-v start="3" \
-v len="17" \
'{
gsub(substr([=10=],start+1,len),"");
gsub(/[\|]/,del1 del2 del1);
print del1[=10=]del1
}' input_file
'X',00000098765432','1234567890','TQ'
使用任何 POSIX awk:
$ echo 'X|001200000000000000000098765432|1234567890|TQ' |
awk -F'|' -v OFS="','" -v q="'" '{sub(/.{16}/,"",); print q [=10=] q}'
'X','00000098765432','1234567890','TQ'
没有我希望的那么优雅,但它完成了工作:
'X','00000098765432','1234567890','TQ'
# gawk profile, created Mon May 9 21:19:17 2022
# BEGIN rule(s)
'BEGIN {
1 _ = sprintf("%*s", (__ = +2)^++__+--__*++__,__--)
1 gsub(".", "[0-9]", _)
1 sub("$", "$", _)
1 FS = "[|]"
1 OFS = ","
}
# Rule(s)
1 (NF *= NF == __*__) * sub(_, "|&", $__) * \
sub("^.*[|]", "", $__) * sub(".+", "&") }'
已在 gnu gawk 5.1.1
、mawk 1.3.4
、mawk 1.9.9.6
和 macosx nawk
—The 4Chan Teller