2

私のテキストファイルは次のようになります

foo.en 14 :: xyz 1;foo bar 2;foofoo 5;bar 9
bar.es 18 :: foo bar 4;kjp bar 2;bar 6;barbar 8

区切り文字の前のテキストを無視して、::で区切られた一意の単語の出力を生成するようなテキストを抽出する 1 つのライナー UNIX コマンド (多くのパイプが許可されている) または 1 つのライナー Perl スクリプトはあります;か? :

xyz
foo bar
foofoo
bar
kjp bar
barbar

Pythonスクリプトを使用してテキストファイルをループしようとしましたが、タスクのワンライナーを探しています。

ans = set()
for line in open(textfile):
  ans.add(line.partition(" :: ")[1].split(";").split(" ")[:-1])

for a in ans:
  print a
4

4 に答える 4

3

Perl の場合:

perl -nle 's/.*?::\s*//;!$s{$_}++ and print for split /\s*\d+;?/' input

説明:

s/.*?::\s*//;  # delete up to the first '::'

この部分:

!$s{$_}++ and print for split /\s*\d+;?/

次のように書き換えることができます。

foreach my $word (split /\s*\d+;?/) {   # for split /\s*\d+;?/
  if (not defined $seen{$word}}) {      # !$s{$_}
    print $word;                        # and print
  }
  $seen{$word}++;                       # $s{$_}++
}

インクリメント イン!$s{$_}++はポスト インクリメントであるため、Perl は最初に false 条件をテストしてからインクリメントを実行します。未定義のハッシュ値の値は です0。テストが失敗した場合、つまり$s{$_}以前にインクリメントされていた場合、andの部分は短絡によりスキップされます。

于 2013-02-27T00:36:18.413 に答える
2
cat textfile | sed 's/.*:://g' |  tr '[0-9]*;' '\n' | sort -u

説明:

sed 's/.*:://g'      Take everything up to and including `::` and replace it with nothing
tr '[0-9];' '\n'     Replace numbers and semicolon with newlines
sort -u              Sort, and return unique instances

ソートされた出力が得られると思います...

于 2013-02-27T00:22:12.660 に答える
1

あなたはこれを試すことができます:

$ awk -F ' :: ' '{print $2}' input.txt | grep -oP '[^0-9;]+' | sort -u
bar 
barbar 
foo bar 
foofoo 
kjp bar 
xyz 

フレーズに数字が含まれている場合は、次の正規表現 を試してください。'[^;]+?(?=\s+\d+(;|$))'

于 2013-02-27T00:24:41.253 に答える
1

のみの場合:

$ awk -F' :: ' '{
    gsub(/[0-9]+/, "")
    split($2, arr, /;/ )
    for (a in arr) arr2[arr[a]]=""
}
END{
    for (i in arr2) print i
}' textfile.txt

そしてワンライナーバージョン:

 awk -F' :: ' '{gsub(/[0-9]+/, "");split($2, arr, /;/ );for (a in arr) arr2[arr[a]]="";}END{for (i in arr2) print i}' textfile.txt
于 2013-02-27T00:33:37.337 に答える