bash - Get first line of stdin which is not in a file -
i trying write function in bash script gets lines stdin , picks out first line not contained in file.
here approach:
doubles=file.txt firstnotdouble(){ while read input_line; found=0; cat $doubles | while read double_line; if [ "$input_line" = "$double_line" ] found=1; break fi done if [ $found -eq 0 ] # no double found, echo , break! echo $input_line break fi done }
after debugging attempts realized when found set 1 in first if block, not keep value until next if block. that's why it's not working. why script act if there 2 found variables in different "scopes"?
the second question if approach whole optimized.
as indicated in comments, issue environment variables commands in pipeline (that is, series of commands separated |
) run in subshells, , each subshell has own environment variables. have avoided problem avoiding uuoc (useless use of cat), writing:
while read ...; ... done < "$doubles"
instead of pipeline.
a (much) faster way using while read
loop repeatedly through doubles file use grep:
# specify file scanned first argument firstnotdouble() { while ifs= read -r double_line; if ! grep -qxf "$double_line" "$1"; echo "$double_line" return fi done return 1 }
in grep
:
-q
suppress print out, , stop on first match-x
pattern must match entire line-f
pattern simple string instead of regular expression.
in read
:
ifs=
avoids spaces being trimmed-r
avoids backslashes being deleted
with gnu grep, use -xf -m1
(or -xfm1
if being cryptic) instead of -qxf
, , leave out echo
. grep extension -m n
limits number of matches found n
.
Comments
Post a Comment