Dize ve ilk kelimeyi içeren kelimeyi yazdır


10

Bir metin satırında bir dize bulmak ve (boşluklar arasında) dize ve deyimin ilk kelimesini yazdırmak istiyorum.

Örneğin:

"Bu tek bir metin satırıdır"
"Başka bir şey"
"Tekrar denemek daha iyi"
"Daha iyi"

Dizelerin listesi:

Metin
şey
Deneyin
Daha iyi

Ne çalışıyorum böyle bir tablo elde etmektir:

Bu [sekme] metin
Başka bir [sekme] şey
[Sekme] denemek
Daha iyi

Grep ile denedim ama hiçbir şey olmadı. Herhangi bir öneri?


Yani, temelde "Satır dizgiyse, ilk kelimeyi + dizgiyi yazdır". Sağ ?
Sergiy Kolodyazhnyy

Yanıtlar:


12

Bash / grep versiyonu:

#!/bin/bash
# string-and-first-word.sh
# Finds a string and the first word of the line that contains that string.

text_file="$1"
shift

for string; do
    # Find string in file. Process output one line at a time.
    grep "$string" "$text_file" | 
        while read -r line
    do
        # Get the first word of the line.
        first_word="${line%% *}"
        # Remove special characters from the first word.
        first_word="${first_word//[^[:alnum:]]/}"

        # If the first word is the same as the string, don't print it twice.
        if [[ "$string" != "$first_word" ]]; then
            echo -ne "$first_word\t"
        fi

        echo "$string"
    done
done

Şöyle deyin:

./string-and-first-word.sh /path/to/file text thing try Better

Çıktı:

This    text
Another thing
It  try
Better

9

Kurtarmaya Perl!

#!/usr/bin/perl
use warnings;
use strict;

my $file = shift;
my $regex = join '|', map quotemeta, @ARGV;
$regex = qr/\b($regex)\b/;

open my $IN, '<', $file or die "$file: $!";
while (<$IN>) {
    if (my ($match) = /$regex/) {
        print my ($first) = /^\S+/g;
        if ($match ne $first) {
            print "\t$match";
        }
        print "\n";
    }
}

Farklı kaydet first-plus-word, farklı çalıştır

perl first-plus-word file.txt text thing try Better

Girdi sözcüklerinden bir normal ifade oluşturur. Daha sonra her satır normal ifadeyle eşleştirilir ve bir eşleşme varsa, ilk sözcük yazdırılır ve sözcükten farklıysa, sözcük de yazdırılır.


9

İşte bir awk sürümü:

awk '
  NR==FNR {a[$0]++; next;} 
  {
    gsub(/"/,"",$0);
    for (i=1; i<=NF; i++)
      if ($i in a) printf "%s\n", i==1? $i : $1"\t"$i;
  }
  ' file2 file1

file2kelime listesi nerede file1ve ifadeleri içeriyor.


2
İyi bir! Bir komut dosyasına koydum, paste.ubuntu.com/23063130 , sadece kolaylık olması için
Sergiy Kolodyazhnyy

8

İşte python sürümü:

#!/usr/bin/env python
from __future__ import print_function 
import sys

# List of strings that you want
# to search in the file. Change it
# as you fit necessary. Remember commas
strings = [
          'text', 'thing',
          'try', 'Better'
          ]


with open(sys.argv[1]) as input_file:
    for line in input_file:
        for string in strings:
            if string in line:
               words = line.strip().split()
               print(words[0],end="")
               if len(words) > 1:
                   print("\t",string)
               else:
                   print("")

Demo:

$> cat input_file.txt                                                          
This is a single text line
Another thing
It is better you try again
Better
$> python ./initial_word.py input_file.txt                                      
This    text
Another     thing
It  try
Better

Yan not : Komut dosyası python3uyumludur, bu nedenle python2veya ile çalıştırabilirsiniz python3.


7

Bunu dene:

$ sed -En 's/(([[:alnum:]]+)[[:space:]].*)?(text|thing|try|Better).*/\2\t\3/p' File
This    text
Another thing
It      try
        Better

Önceki sekme Betterbir sorunsa, şunu deneyin:

$ sed -En 's/(([[:alnum:]]+)[[:space:]].*)?(text|thing|try|Better).*/\2\t\3/; ta; b; :a; s/^\t//; p' File
This    text
Another thing
It      try
Better

Yukarıdakiler GNU sed (OSX'de denir) gsedüzerinde test edilmiştir . BSD sed için bazı küçük değişiklikler gerekebilir.

Nasıl çalışır

  • s/(([[:alnum:]]+)[[:space:]].*)?(text|thing|try|Better).*/\2\t\3/

    Bu, bir sözcük, [[:alnum:]]+ardından bir boşluk [[:space:]], ardından herhangi bir şey .*, ardından kelimelerinizden birini ve ardından herhangi bir şeyi arar text|thing|try|Better. Eğer bulunursa, satırdaki ilk kelime (varsa), bir sekme ve eşleşen kelime ile değiştirilir.

  • ta; b; :a; s/^\t//; p

    İkame komutu bir ikame ile sonuçlandıysa, yani kelimelerinizden birinin satırda bulunduğu anlamına gelirse, komut tased'e etikete atlamasını söyler a. Değilse b, bir sonraki satıra ( ) geçiyoruz. :aa etiketini tanımlar. Yani, kelimelerinizden biri bulunursa, (a) s/^\t//varsa baştaki sekmeyi kaldıran ikame işlemini yaparız ve (b) psatırı yazdırırız ( ).


7

Basit bash / sed yaklaşımı:

$ while read w; do sed -nE "s/\"(\S*).*$w.*/\1\t$w/p" file; done < words 
This    text
Another thing
It  try
    Better

while read w; do ...; done < wordsDosyasındaki her satır üzerinde yineleme olacak wordsve olarak kaydedin $w. -nMarkaları sedvarsayılan olarak hiçbir şey yazdırmıyor. sedKomut sonra, sigara Arkasında boşluk çift tırnak yerini alacak ( \"(\S*)parantezler ile eşleşen ne "yakalama" hizmet \S*İlk kelime ve daha sonra o sonuca başvurabilir \1) (0 veya daha fazla karakter .*sonra) ve Aradığınız kelime ( $w) ve tekrar 0 veya daha fazla karakter ( .*). Bu maçlarda, biz sadece 1 kelime, bir sekme ve ile değiştirin $w( \1\t$w) ve (en neyi o çizgiyi basmak piçinde s///pyapar).


5

Bu Ruby versiyonu

str_list = ['text', 'thing', 'try', 'Better']

File.open(ARGV[0]) do |f|
  lines = f.readlines
  lines.each_with_index do |l, idx|
    if l.match(str_list[idx])
      l = l.split(' ')
      if l.length == 1
        puts l[0]
      else
        puts l[0] + "\t" + str_list[idx]
      end
    end
  end
end

Örnek metin dosyası hello.txtiçeriyor

This is a single text line
Another thing
It is better you try again
Better

ruby source.rb hello.txtSonuçlarla çalıştırma

This    text
Another thing
It      try
Better
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.