scrambledA.txt
私のリストには次のデータがあります。
efrrsu
aehmmr
aeeglnr
alnors
acflno
aaahmy
aceimru
1469en
aelprsy
cehrry
そして、wordlistC.txt
多くのキーと値のペアを含む対応は次のとおりです。
...-...
...-...
1469en-ne1469
aaahmy-yamaha
aceimru-maurice
acflno-falcon
aeeglnr-general
aehmmr-hammer
aelprsy-players
alnors-larson
cehrry-cherry
efrrsu-surfer
...-...
...-...
scrambledA.txt
myをの正しい単語と一致させようとしていますwordlistC.txt
。まず試しました
grep -f scrambledA.txt wordlistC.txt | cut -d'-' -f2
scrambledA.txt
ただし、必要な順序で出力は提供されません。それからforループを使って何かをする必要があると思いましたが、うまくいくことはできませんでした。私が何を間違っているのでしょうか?
for line in $(cat "scrambledA.txt")
do
#grep -f "$line" wordlistC >> scrambledBB.txt
#echo $line | grep -f wordlistC.txt >> scrambledBBB.txt
done
予想される出力は次のとおりです。
surfer
hammer
general
larson
falcon
yamaha
maurice
ne1469
players
cherry
答え1
厳密に言えば、はい入力ファイルに表示される順序で単語を取得します。単に「入力ファイル」がgrep
混在した単語リストではなく、単語リストファイルというだけです。
grep
現在のオプションと一緒に提供するのは-f
混在した単語のリストですが、実際に一致させるパターンではありません。一致させるパターンは、単語リストファイルのキー(-
各行の最初の文字列の前の文字列)です。あなたは一致したいですそれらスクランブルされたファイルの単語を比較して、対応するスクランブルされていない文字列を見つけます。
awk
単語リストを連想配列として読み取った後、その配列の間違ったファイルから各行について読み取った単語を見つけると、これはかなり簡単になります。
$ awk -F - '!wordlist_processed { dict[$1]=$2; next }
{ print $0 in dict ? dict[$0] : "UNKNOWN WORD" }
' wordlistC.txt wordlist_processed=1 scrambledA.txt
surfer
hammer
general
larson
falcon
yamaha
maurice
ne1469
players
cherry
UNKNOWN WORD
また、単語リストにキーとして表示されない混乱した単語の文字列も追加で印刷されます。
まったく異なるアプローチは、単語リストをスクリプトに変換し、sed
入力の単語を置き換えることです。
$ sed 's,\([^-]*\)-\(.*\),s/^\1$/\2/;t,' wordlistC.txt | sed -f /dev/stdin scrambledA.txt
surfer
hammer
general
larson
falcon
yamaha
maurice
ne1469
players
cherry
最初のsed
コマンドはスクリプトを生成し、2番目のコマンドはsed
スクランブルされた単語に適用します。質問の例(...
-entriesが削除されました)を考えると、スクリプトは次のようになります。
s/^1469en$/ne1469/;t
s/^aaahmy$/yamaha/;t
s/^aceimru$/maurice/;t
s/^acflno$/falcon/;t
s/^aeeglnr$/general/;t
s/^aehmmr$/hammer/;t
s/^aelprsy$/players/;t
s/^alnors$/larson/;t
s/^cehrry$/cherry/;t
s/^efrrsu$/surfer/;t
(単語リストの単語をそのまま使用しています。つまり、キーは正しい正規表現でなければならず、混在しない単語は置換コマンドの右側に含まれるように有効でなければなりません。sed
)
ご覧のとおり、各置換は、1行で個別に混在した特定の単語と一致し、それを混在させない単語に置き換えます。置換が行われると、各置換の後のベアコマンドはt
スクリプトの最後に分岐します。これは入力ラインでの複数の置換を防ぐためです。
上記の両方の方法は、復号化するために混乱した単語に「単語リストを適用」します。その逆ではなく、それがあなたの質問でやっていることです。
答え2
wordlistC.txt
メモリで完全に読み取れたら、scrambledA.txt
次のようにコンテンツを復号化できますawk
。
awk -F'-' '
# Save lookup key/value
FNR==NR { w[$1]=$2 }
# Lookup or error
FNR<NR { if($1 in w) { print w[$1] } else { print "Unknown:", $1 } }
' wordlistC.txt scrambledA.txt
出力
surfer
hammer
general
larson
falcon
yamaha
maurice
ne1469
players
cherry
答え3
リストの順序を維持する必要がある一般的な技術は次のとおりです。番号を追加処理する前に処理してください。この番号を保管して使用する準備タイプ処理後に可能です。切る数字が出ました。
nl scrambledA.txt | … | sort -k1n | cut -f2
あなたはそれを使用することができますjoin
フィールド値に基づいて2つのファイルの行をマージします。両方の入力は共通フィールドに基づいてソートする必要があります。サインアップするときは、混在したファイルの数と単語リストの混在した単語を保持してください。もう混乱した言葉は必要ありません。
nl scrambledA.txt | sort -k2 |
join -t $'\t' -1 2 -2 1 -o 1.1,2.2 - <(<wordlistC.txt tr - \\t | sort) |
sort -t $'\t' -k1n | cut -f2
答え4
使用幸せ(以前のPerl_6)
#taking scrambledA.txt inline:
~$ raku -ne 'BEGIN my @scrambled = <efrrsu aehmmr aeeglnr alnors acflno aaahmy aceimru 1469en aelprsy cehrry>;
state %hash;
%hash.append: $_.split("-");
END put %hash{$_} // next for @scrambled;' wordlistC.txt
または:
#taking scrambledA.txt using a filepath:
~$ raku -ne 'BEGIN my @scrambled = "/path/to/scrambledA.txt".IO.lines;
state %hash;
%hash.append: $_.split("-");
END put %hash{$_} // next for @scrambled;' wordlistC.txt
上記は、Perlシリーズのプログラミング言語であるRakuで書かれた答えです。 Rakuは、-ne
非自動印刷(同様の)行ごとのコマンドラインフラグを使用してawk
呼び出されます。
Perlと同様に、Rakuにはハッシュ(連想配列/辞書など)が組み込まれています。上記で使用された戦略は、目的の@
出力順序を維持するためにスクランブルされた単語を-sigiled配列にインポートすることです(上記の2つの方法のいずれかでスクランブルされた単語を取得します)。次に、関連付けられた単語のリストは、歪んだ単語と一般的な単語で構成されるsplit
ものを作成します。%hash
key
value
END
最後に、ブロックで@scrambled
配列を繰り返しますfor
。ハッシュをハッシュして各要素(キー)を見つけ、%hash{$_}
見つかったらその値を出力します。value
入力例(scrambledA.txt):
efrrsu
aehmmr
aeeglnr
alnors
acflno
aaahmy
aceimru
1469en
aelprsy
cehrry
入力例(wordlistC.txt):
1469en-ne1469
aaahmy-yamaha
aceimru-maurice
acflno-falcon
aeeglnr-general
aehmmr-hammer
aelprsy-players
alnors-larson
cehrry-cherry
efrrsu-surfer
出力例:
surfer
hammer
general
larson
falcon
yamaha
maurice
ne1469
players
cherry
wordlistC.txt
ファイルに見つからない順序が間違った単語をスキップするには、(定義または次)を使用してください。// next
一致を返すのではなく、定義または演算子の右側を(空の文字列)に変更して、一致しない項目の空白行を残すこともできます。それ以外の場合は、より詳細なフィードバックが必要な場合は、次のように必要な文字列を追加してください。next
//
""
END put %hash{$_} // "Unknown: $_" for @scrambled;`
https://docs.raku.org/言語/hashmap#Hashes_and_maps
https://docs.raku.org/
https://raku.org