
2つのファイルを1行ずつ比較する必要があります。私は他の行だけを出力したいのですが、違いを判断するときは、文字4-6と10-12は無視する必要があります。特定のフィールド区切り記号などはありません。
例:
- ファイル1
abc123def999 ghi456klm999 nop789qrs999
- ファイル2
abc000def000 xxx000yyy000 nop000qrs000
この例では、2番目の行だけが異なる必要があります。
read
ファイルには何百万ものレコードがあるため、ループがファイルを1行ずつ解析することは望ましくありません。
答え1
GNU awkをFIELDWIDTHSパラメータとして使用する:
$ paste file[12] |
awk -v FIELDWIDTHS='3 3 3 3 1 3 3 3 3' '$1!=$6 || $3!=$8'
ghi456klm999 xxx000yyy000
paste
ここでは、2つのファイルを並べて貼り付けるコマンドを使用します。次に、awkのFIELDWIDTHSパラメーターを使用してフィールド長を定義するため、2つのファイルの行が固定長であると仮定し、ここで関連フィールドの違いを比較します。一行ずつ行われます。
または、すべてのシェルで awk を使用します。
$ paste file[12] |
awk 'function key(s){return substr(s,1,3) substr(s,7,3)} key($1) != key($2)'
ghi456klm999 xxx000yyy000
答え2
予想される出力を示しておらず、要件が何であるかを実際に知らせていないので、以下はすべてのUnixシステムのすべてのシェルでawkを使用して必要なものを推測します.
$ cat tst.awk
{ key = substr($0,1,3) substr($0,7,3) }
NR == FNR {
a[key]
next
}
!(key in a)
$ awk -f tst.awk file1 file2
xxx000yyy000
$ awk -f tst.awk file2 file1
ghi456klm999
答え3
どちらのファイルにも「何百万ものレコード」がありますか?短いファイルを選択し、各行を読み、「^
(行の先頭)で$
始まり、」(行の終わり)で終わる正規表現を生成します。検索文字列はその間にあります。無視する位置を「.
」(正規表現「すべての単一文字に一致」)に設定します。例えば" ^abc...def...$
"。一時ファイル(file1.tmp
)に保存します(何百万?)。すべての行を処理すると、inはgrep -E -f file1.tmp file2
正規表現を検索します。file1.tmp
file2
答え4
方法1)perl
このunpack
機能は、Perl環境トレイに提供されている形式に基づいて特定の範囲の文字を抽出するため、この状況に最適です。(A3x3)2A*
=> 3つのASCII文字を選択し、3つの文字をスキップします。このプロセスをもう一度繰り返して、残りのものを取得します。
fmt='(A3x3)2A*' \
perl -nse 'print if "@{[unpack($ENV{fmt})]}" ne
"@{[unpack($ENV{fmt},scalar(<STDIN>))]}";
' -- -\"= File1 < File2
ghi456klm999
方法-2)paste+GNU sed
貼り付けは、2つのファイルの対応する行をタブで区切って並べて配置します。したがって、ファイルにタブがあってはならないとします。次に、2つのファイルのデータで、4-6文字と10-12文字を同じ文字「.」に置き換えます。行を比較する前にInesが一致しない場合は、file1行を印刷します。
# helper vars aid in writing sed code
x3='...'
A3="($x3)"
A3x3=$A3$x3
srch="^$A3x3$A3x3"
repl="\\1$x3\\2$x3"
paste File1 File2 |
sed -En 'y/\t/\n/;h
'"s/$srch/$repl/Mg"'
/^(.*)\n\1$/d;g;P
' -
方法-3)Python
組み込みのzip機能は、2つのファイルの行を並べて表示します。
python3 -c 'import sys
# skip chars: 4-6 10-12
AoT = [(0,3),(6,9),(12,None)] # array of tuples
fx = lambda t: \
a[t[0]:t[1]] != b[t[0]:t[1]]
ifile1,ifile2 = sys.argv[1:]
with open(ifile1) as f1,\
open(ifile2) as f2:
for a,b in zip(f1,f2):
if any(map(fx,AoT)):
print(a,end="")
' File1 File2