Cetak kata yang berisi string dan kata pertama

10

Saya ingin menemukan string dalam baris teks dan mencetak string (antara spasi) dan kata pertama dari frasa.

Sebagai contoh:

"Ini adalah satu baris teks"
"Hal lain"
"Lebih baik kamu coba lagi"
"Lebih baik"

Daftar string adalah:

teks
benda
mencoba
Lebih baik

Apa yang saya coba adalah untuk mendapatkan tabel seperti ini:

Teks [tab] ini
[Tab] lain hal
Itu [tab] mencoba
Lebih baik

Saya mencoba dengan grep tetapi tidak ada yang terjadi. Ada saran?

Felipe Lira
sumber
Jadi, pada dasarnya "Jika baris memiliki string, cetak kata pertama + string". Baik ?
Sergiy Kolodyazhnyy

Jawaban:

12

Versi bash / grep:

#!/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

Sebut seperti ini:

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

Keluaran:

This    text
Another thing
It  try
Better
wjandrea
sumber
9

Perl untuk menyelamatkan!

#!/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";
    }
}

Simpan sebagai first-plus-word, jalankan sebagai

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

Itu menciptakan regex dari kata-kata input. Setiap baris kemudian dicocokkan dengan regex, dan jika ada kecocokan, kata pertama dicetak, dan jika berbeda dengan kata, kata tersebut juga dicetak.

choroba
sumber
9

Ini versi awk:

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

di mana file2daftar kata dan file1berisi frasa.

Steeldriver
sumber
2
Bagus Saya telah memasukkannya ke file skrip, paste.ubuntu.com/23063130 , hanya untuk kenyamanan
Sergiy Kolodyazhnyy
8

Inilah versi python:

#!/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

Catatan : Skrip ini python3kompatibel, sehingga Anda dapat menjalankannya dengan python2atau python3.

Sergiy Kolodyazhnyy
sumber
7

Coba ini:

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

Jika tab sebelum Bettermasalah, maka coba ini:

$ 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

Di atas diuji pada GNU sed (dipanggil gsedpada OSX). Untuk BSD sed, beberapa perubahan kecil mungkin diperlukan.

Bagaimana itu bekerja

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

    Ini mencari kata, [[:alnum:]]+diikuti oleh spasi [[:space:]], diikuti oleh apa pun .*, diikuti oleh salah satu kata Anda text|thing|try|Better, diikuti oleh apa pun. Jika itu ditemukan, itu diganti dengan kata pertama pada baris (jika ada), tab, dan kata yang cocok.

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

    Jika perintah substitusi menghasilkan substitusi, yang berarti bahwa salah satu kata Anda ditemukan di telepon, maka taperintah itu memberitahu sed untuk melompat ke label a. Jika tidak, maka kita cabang ( b) ke baris berikutnya. :amendefinisikan label a. Jadi, jika salah satu dari kata-kata Anda ditemukan, kami (a) melakukan substitusi s/^\t//yang menghilangkan tab utama jika ada, dan (b) mencetak ( p) baris.

John1024
sumber
7

Pendekatan bash / sed sederhana:

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

The while read w; do ...; done < wordsakan iterate atas setiap baris dalam file wordsdan simpan sebagai $w. The -nmerek sedtidak mencetak apa pun secara default. The sedperintah maka, akan menggantikan tanda kutip ganda diikuti oleh non-spasi ( \"(\S*), tanda kurung berfungsi untuk "menangkap" apa yang cocok dengan \S*, kata pertama, dan kami kemudian dapat menyebutnya sebagai \1), 0 atau lebih karakter ( .*) dan kemudian kata yang kami cari ( $w) dan 0 atau lebih karakter lagi ( .*). Jika ini cocok, kami menggantinya dengan hanya kata pertama, tab dan $w( \1\t$w), dan mencetak baris (itulah yang dilakukan pdi s///p).

terdon
sumber
5

Ini adalah versi Ruby

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

File teks sampel hello.txtberisi

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

Berjalan dengan ruby source.rb hello.txthasil dalam

This    text
Another thing
It      try
Better
Anwar
sumber