我想用来awk
解析一个文件,并添加一行,当且仅当该行尚不存在时。
我的文件:
cccc
dddd
aaaa
mmm
实施例1: 我在找 ”啊啊啊”
“aaaa”存在,所以什么也没有发生,输出文件将是相同的。
实施例2: 我在找 ”布布”
“bbbb”不存在。我的输出文件应该是:
cccc
dddd
aaaa
mmm
bbbb
我怎样才能得到这个结果?
答案1
$ awk -v x='aaaa' '$0 == x {found=1} END {if(!found) print x} 1' file
cccc
dddd
aaaa
mmm
$ awk -v x='bbbb' '$0 == x {found=1} END {if(!found) print x} 1' file
cccc
dddd
aaaa
mmm
bbbb
答案2
如果你想一次处理这个
line=aaaa
grep -Fx -q "$line" file || echo "$line" >> file
如果您预先知道所有可能性,那么这可能会更有效:
$ cat lines_to_add
aaaa
bbbb
$ grep -Fx -f file -v lines_to_add >> file
$ cat file
cccc
dddd
aaaa
mmm
bbbb
答案3
如果您有 GNU sed,这是一个很酷的选择:
$ sed -z '/bbbb/!s/$/bbbb\n/' file > file.out
$ cat file.out
cccc
dddd
aaaa
mmm
bbbb
该-z
标志使 sed 将文件解释为空字节分隔而不是换行分隔。这样,所有行都会立即进入模式空间,如果在整个文件中找不到正则表达式 ( /bbbb/!
),则未找到的行和换行符将附加到文件末尾 ( s/$/bbbb\n/
)。根据 POSIX 标准,最后一个换行符是必需的,否则输出文件将不是文本文件。
如果您想将该行提供为变量:
line=bbbb
sed -z /"$line"'/!s/$/'"$line"'\n/' file > file.out
答案4
使用 awk 执行此操作的一种方法是提供输入文件两次。
$ awk '
FNR == NR { next }
/bbbb/, 0 { print; next }
NR == 2*FNR { $0 = $0 ORS "bbbb"}1
' file file
与上面相同的方法,但使用 sed 命令:
sed -e '
/bbbb/,$b
$a bbbb
' file