Как фильтровать многострочные файлы с помощью awk, grep и/или powershell

Что не работает

Bash не поддерживает многопоточный параллелизм, только многопроцессорный параллелизм -.

В Bash нет возможности запустить цикл for (или канал, если уж на то пошло )в фоновом режиме, не порождая дочерний процесс. Меня удивляет, что процессов bash 20, а не 21.

Я ничего не знаю о Cygwin.


Альтернативы

Если вы немного знакомы с Python, я предлагаю вам использовать библиотеку Plumbum для выполнения вашего вызова. Python поддерживает многопоточность, и это все упростит.

Вот ваш код, переписанный и протестированный:

from datetime import datetime
import json
import random
from plumbum import cmd as c
from threading import Thread

def now():
    return datetime.now().strftime("%Y-%m-%d %H_%M_%S")

logdir = f"~/curl_result_{now()}"

def curl(threadno, reqno):
    args1 = "--verbose -sS http://dummy.restapiexample.com/api/v1/create --trace-ascii".split()
    args2 = [f"{logdir}_{threadno}_{reqno}", "-d", "@-"]
    content = json.dumps({
        "name": f"{logdir}/trace_{threadno}_{reqno}_{now()}",
        "salary": random.randrange(100_000),
        "age": random.randrange(100_000),
    })
    call = c.echo[content] | c.curl[(*args1, *args2)] >> f"{logdir}/response_{threadno}"
    print(call)
    # call()

def curl_batch(threadno):
    for reqno in range(20):
        curl(threadno, reqno)

# Start 20 threads
threadList = []
for threadno in range(20):
    t = Thread(target=curl_batch, args=(threadno,))
    t.start()
    threadList.append(t)

# Wait for every thread
for thread in threadList:
    thread.join()

Наслаждайтесь гибкостью Python;)

0
18.04.2021, 23:48
1 ответ

При наличии исходного файла , следующее удалит все заголовки, в которых не упоминается (USA)в атрибуте namenameузла заголовка rom:

xmlstarlet ed -d '//game[not(contains(rom/@name, "(USA)"))]' file-orig.xml >file-new.xml

Выражение XPath //game[not(contains(rom/@name, "(USA)"))]выбирает все gameузлы, у которых есть хотя бы один romподузел -с атрибутом name, который не содержит строку (USA). Они выбраны для удаления.

Вывод записывается в новый файл с использованием перенаправления в командной строке.

Посмотрев некоторое время на XML-данные, я заметил, что вместо того, чтобы смотреть на romузлы,кажется, достаточно посмотреть атрибут nameосновного gameузла:

xmlstarlet ed -d '//game[not(contains(@name, "(USA)"))]' file-orig.xml >file-new.xml

Удаляются все игры, не содержащие (USA)в атрибуте nameузла game.

Файл, который я скачал, будет содержать 1979 заголовков после удаления всех заголовков, отличных от -(USA).

Чтобы дополнительно отфильтровать все не-Gamesкатегории:

xmlstarlet ed \
    -d '//game[not(contains(@name, "(USA)"))]' \
    -d '//game[category != "Games"]' file-orig.xml >file-new.xml

Остается 1474 названия игр.

Просто для удовольствия, чтобы отсортировать названия игр по их общему размеру:

xmlstarlet ed \
    -d '//game[not(contains(@name, "(USA)"))]' \
    -d '//game[category != "Games"]' file-orig.xml |
xmlstarlet sel -t -m '//game' \
    -v 'sum(rom/@size)' -o ' ' -v '@name' -nl | sort -n
3
28.04.2021, 22:52

Теги

Похожие вопросы