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?


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

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.


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.


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.


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.


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).


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.