, потому что, dict2 = dict1, dict2 содержит ссылку на dict1. Оба dict1 и dict2 указывают на то же место в памяти. Это обычный случай при работе с изменяемыми объектами в python. Когда вы работаете с изменяемыми объектами в python, вы должны быть осторожны, поскольку его трудно отлаживать. Например, в следующем примере.
my_users = {
'ids':[1,2],
'blocked_ids':[5,6,7]
}
ids = my_users.get('ids')
ids.extend(my_users.get('blocked_ids')) #all_ids
print ids#output:[1, 2, 5, 6, 7]
print my_users #output:{'blocked_ids': [5, 6, 7], 'ids': [1, 2, 5, 6, 7]}
Это примерное намерение состоит в том, чтобы получить все идентификаторы пользователей, включая заблокированные идентификаторы. То, что мы получили от переменной ids, но также непреднамеренно обновили значение my_users . когда вы расширили ids с помощью заблокированных_id , мои пользователи обновились, потому что ids относятся к my_users .
Если Perl-решение подходит, вот прямое с тем же регулярным выражением, что и для GNU grep:
perl -ne 'print "$. : $ARGV\n" if /FirstWord((?!SecondWord).)*$/; close ARGV if eof' File?.txt
Как использовать эту команду во всех источниках / папках для все файлы .txt?
blockquote>Для этого вы можете использовать
find
:find Source -name \*.txt|xargs perl …
(без
File?.txt
в конце командыperl
).
В моем примере я хочу знать, когда SecondWord отсутствует, когда FirstWord был написан ранее.
blockquote>Если у вас есть
[110 ]grep
, который понимает регулярные выражения perl, вы можете напрямую указать шаблон для FirstWord, за которым не следует SecondWord где-либо до конца строки :Это приводит к приведенным примерам:
File1.txt:3:... FirstWord ... File1.txt:5:FirstWord ... ... File2.txt:2:FirstWord ...
Чтобы переставить это в желаемый формат вывода, вы можете передать его через
awk -F: '{print $2,":",$1}'
Если оболочкой является bash
, проблему можно легко решить с помощью оператора расширенного сопоставления с образцом !(pattern)
, который соответствует чему угодно, кроме заданного шаблона :
shopt -s extglob # enable extended pattern matching features
for file in "$@"
do lineno=0
while read line
do ((++lineno))
case "$line" in *FirstWord!(*SecondWord)) echo $lineno : $file
esac
done <$file
done