我有一个包含以下内容的平面文件:
11|30646|654387|020751520
11|23861|876521|018277154
11|30645|765418|016658304
使用shell脚本,我想在这个文件中的某些行附加一个字符串,如果这些行包含一个特定的字符串。
例如,在上面的文件中,对于包含23861的行,我想在末尾添加一个字符串“Processed”,以便该文件变为:
11|30646|654387|020751520
11|23861|876521|018277154|Processed
11|30645|765418|016658304
我可以使用sed将字符串附加到文件中的所有行,但是如何为特定行添加?
答案 0 :(得分:3)
我会这样做
sed '/\|23861\|/{s/$/|Something/;}' file
这与Marcelo的答案类似,但不需要扩展表达式,而且我认为更清洁。
首先,匹配管道之间有23861
的行
/\|23861\|/
然后,在这些行上,用字符串|Something
{s/$/|Something/;}
如果你想做多个这样的事情,你可以简单地列出它们
sed '/\|23861\|/{s/$/|Something/;};/\|30645\|/{s/$/|SomethingElse/;}' file
答案 1 :(得分:1)
使用以下awk-script:
$ awk '/23861/ { $0=$0 "|Processed" } {print}' input
11|30646|654387|020751520
11|23861|876521|018277154|Processed
11|30645|765418|016658304
或使用sed
:
$ sed 's/\(.*23861.*$\)/\1|Processed/' input
11|30646|654387|020751520
11|23861|876521|018277154|Processed
11|30645|765418|016658304
答案 2 :(得分:1)
使用替换命令:
sed -i~ -E 's/(\|23861\|.*)/\1|Processed/' flat.file
(注意:-i~
就地执行替换。如果您不想修改原始文件,请将其删除。)
答案 3 :(得分:0)
你可以使用shell
while read -r line
do
case "$line" in
*23681*) line="$line|Processed";;
esac
echo "$line"
done < file > tempo && mv tempo file
答案 4 :(得分:0)
sed只是ed的流版本,它有一个类似的命令集,但设计用于编辑文件(据称是交互式的,但你不想这样使用它,除非你所拥有的只是these之一。像
这样的东西field_2_value=23861
appended_text='|processed'
line_match_regex="^[^|]*|$field_2_value|"
ed "$file" <<EOF
g/$line_match_regex/s/$/$appended_text/
wq
EOF
应该让你到那儿。
请注意, / s / $ / 中的 $ ... 不由shell扩展,< strong> $ line_match_regex 和 $ attached_text ,因为没有 $ / 这样的东西 - 而是按原样传递给 ed ,将其解释为要替换的文本( $ 正则表达式代表“行尾”)。
在sed中执行相同作业的语法,如果您想要对流而不是文件执行此操作,则非常相似,除非您在正则表达式地址之前不需要前导g:
sed -e "/$line_match_regex/s/$/$appended_text/" "$input_file" >"$output_file"
您需要确保放在 field_2_value 和 attached_text 中的值永远不会包含斜杠,因为ed的 g 和 s 命令用于分隔符。
如果他们可以这样做,并且您正在使用bash或其他允许 $ {name // search / replace} 参数扩展语法的shell,您可以通过替换来动态修复它们扩展这些变量时,每个 / 都 \ / 。因为bash还使用 / 作为替换分隔符并使用 \ 作为字符转义符,所以最终看起来很糟糕:
appended_text='|n/a'
ed "$file" <<EOF
g/${line_match_regex//\//\\/}/s/$/${appended_text//\//\\/}/
wq
EOF
但确实有效。注意 ed 和 sed 在 s / search / replace / 中替换文本后需要尾随 / bash的 $ {name // search / replace} 语法没有。