พิมพ์คำที่มีสตริงและคำแรก


10

ฉันต้องการค้นหาสตริงในบรรทัดข้อความและพิมพ์สตริง (ระหว่างช่องว่าง) และคำแรกของวลี

ตัวอย่างเช่น:

"นี่คือบรรทัดข้อความเดียว"
"อีกสิ่งหนึ่งที่"
"จะดีกว่าถ้าคุณลองอีกครั้ง"
"ดีกว่า"

รายการของสตริงคือ:

ข้อความ
สิ่ง
ลอง
ดีกว่า

สิ่งที่ฉันพยายามคือการได้รับตารางเช่นนี้

ข้อความ [แท็บ]
อีกสิ่ง [แท็บ]
ลอง [แท็บ]
ดีกว่า

ฉันลองใช้ grep แต่ไม่มีอะไรเกิดขึ้น ข้อเสนอแนะใด ๆ


ดังนั้นโดยพื้นฐานแล้ว "ถ้าบรรทัดมีสตริงให้พิมพ์คำแรก + สตริง" ใช่มั้ย
Sergiy Kolodyazhnyy

คำตอบ:


12

รุ่น 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

เรียกว่าเป็นเช่นนั้น:

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

เอาท์พุท:

This    text
Another thing
It  try
Better

9

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";
    }
}

บันทึกเป็นfirst-plus-wordเรียกใช้เป็น

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

มันสร้าง regex จากคำที่ป้อน แต่ละบรรทัดจะจับคู่กับ regex และหากมีการจับคู่คำแรกจะถูกพิมพ์และถ้ามันแตกต่างกับคำว่าคำที่พิมพ์


9

นี่คือรุ่น 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

file2รายการคำอยู่ที่ไหนและfile1มีวลี


2
สิ่งที่ดี! ฉันได้ใส่ลงในไฟล์สคริปต์paste.ubuntu.com/23063130เพียงเพื่อความสะดวก
Sergiy Kolodyazhnyy

8

นี่คือเวอร์ชั่นของงูหลาม:

#!/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("")

การสาธิต:

$> 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

บันทึก Side : สคริปต์python3เข้ากันได้เพื่อให้คุณสามารถทำงานได้กับทั้งหรือpython2python3


7

ลองสิ่งนี้:

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

หากแท็บก่อนBetterเกิดปัญหาให้ลองทำดังนี้:

$ 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

ข้างต้นได้รับการทดสอบบน GNU sed (เรียกว่าgsedบน OSX) สำหรับ BSD sed อาจจำเป็นต้องมีการเปลี่ยนแปลงเล็กน้อย

มันทำงานอย่างไร

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

    สิ่งนี้จะมองหาคำ[[:alnum:]]+ตามด้วยช่องว่าง[[:space:]]ตามด้วยสิ่งใดก็ตาม.*ตามด้วยคำใดคำหนึ่งของคุณtext|thing|try|Betterตามด้วยสิ่งใดก็ตาม หากพบว่ามันถูกแทนที่ด้วยคำแรกในบรรทัด (ถ้ามี), แท็บและคำที่ตรงกัน

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

    ถ้าคำสั่งเปลี่ยนตัวส่งผลให้เปลี่ยนตัวหมายความว่าหนึ่งในคำพูดของคุณถูกค้นพบในบรรทัดแล้วtaคำสั่งบอก sed aเพื่อข้ามไปยังป้าย ถ้าไม่เช่นนั้นเราจะแยก ( b) ไปยังบรรทัดถัดไป :aกำหนดฉลาก ดังนั้นหากพบคำใดคำหนึ่งของคุณเรา (a) ทำการทดแทนs/^\t//ซึ่งจะลบแท็บนำถ้ามีหนึ่งคำและ (b) พิมพ์ ( p) บรรทัด


7

bash / sed ง่าย ๆ :

$ 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 < wordsจะย้ำกว่าแต่ละบรรทัดในไฟล์และบันทึกเป็นwords ทำให้ไม่ได้พิมพ์อะไรไปโดยปริยาย คำสั่งแล้วจะเข้ามาแทนที่คำพูดสองตามมาด้วยที่ไม่ใช่ช่องว่าง ( วงเล็บให้บริการเพื่อ "จับ" สิ่งที่จับคู่โดยคำแรกและเราภายหลังสามารถเรียกมันว่า), 0 หรือมากกว่าตัวอักษร ( ) แล้ว คำที่เรากำลังค้นหา ( ) และ 0 หรือมากกว่าตัวอักษรอีกครั้ง ( ) หากแมตช์นี้เราแทนที่ด้วยเพียงคำ 1 แท็บและ( ) และพิมพ์บรรทัด (ที่ว่าในไม่)$w-nsedsed\"(\S*)\S*\1.*$w.*$w\1\t$wps///p


5

นี่คือรุ่น 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

ไฟล์ข้อความตัวอย่างhello.txtมี

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

ทำงานกับruby source.rb hello.txtผลลัพธ์ใน

This    text
Another thing
It      try
Better
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.