如何使用shell脚本附加到平面文件中的特定行

时间:2011-09-14 11:28:31

标签: shell

我有一个包含以下内容的平面文件:

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将字符串附加到文件中的所有行,但是如何为特定行添加?

5 个答案:

答案 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} 语法没有。

相关问题