Использовать массивы и циклы if или for и выводить отдельные файлы - PullRequest
1 голос
/ 03 апреля 2019

Мой офис получает текстовые 7 текстовых файлов по 10 000 строк текста, каждый длиной 163 символа.Текстовая строка заканчивается почтовыми индексами в виде 5-значных или 10-символьных строк (например, ххххх или ххххх-хххх).Я пытаюсь написать скрипт, который будет читать текстовые файлы и выводить отфильтрованные текстовые файлы в их почтовые округа

Я взял один файл и добился успеха и получаю вывод определенных почтовых индексов с этим:

$content | Select-String -Pattern ".{153}006[0-9]{2,}"

Я установил массивы для каждого округа с пустым массивом, в котором почтовые индексы не-CA будут сортироваться в Reno.Я не дошел до того, что поместил значения в reno.

Код

$LA = 900,901,902,903,904,905, 907, 908
$Industry = 906, 917, 918
$SantaClarita = 910,916
$SanDiego = 919,921
$SanBernardino= 922,925
$SantaAna = 926,927
$Anaheim = 928
$SantaBarbara = 930, 931, 934
$Bakersfield = 932, 933, 935
$Fresno = 936, 937, 938
$SanJose = 939, 950, 951
$SanFrancisco = 940, 941, 943, 944, 949, 954
$Sacramento = 942, 952, 953, 956, 957,958,959
$Oakland = 945..948
$Eureka = 955
$Redding = 960
[String]$Reno = @()

<#put values into $Reno
if (values are not in $zipcodes){$reno = $_}

Please excuse the formatting#>

Я бы хотел, чтобы скрипт работал так:

$content = get-content -path .\*txt

if ($content | Select-String -Pattern ".{153}$LA[0-9]{2,}")
      {
      out-file -path .$LA.txt
      }

и так далее.и так далее, и значения не найдены при переходе к reno.txt

Выходной текст:

<153 Characters>xxxxx     
<153 Characters>xxxxx-xxxx

Строки ввода

123456          92345555                                                                2570 S Fake St    AVE                       280SNO                      CA  93725-1724
123456          92345555                                                                2560 S Fake St    AVE                       280SNO                      CA  93725-1124

1 Ответ

0 голосов
/ 03 апреля 2019

Я чувствую, что это может быть лучше, если создать хеш-таблицу для отслеживания того, в какой город отправляется каждый код, а затем использовать его для поиска. Затем вы можете использовать группу перехвата, сослаться на нее в хеш-таблицу и покончить с ней.

$CityHT = @{}
900,901,902,903,904,905, 907, 908 | %{$CityHT.Add($_.ToString(),"LA.txt")}
906, 917, 918 | %{$CityHT.Add($_.ToString(),"Industry.txt")}
910,916 | %{$CityHT.Add($_.ToString(),"SantaClarita.txt")}
919,921 | %{$CityHT.Add($_.ToString(),"SanDiego.txt")}
922,925 | %{$CityHT.Add($_.ToString(),"SanBernardino.txt")}
926,927 | %{$CityHT.Add($_.ToString(),"SantaAna.txt")}
928 | %{$CityHT.Add($_.ToString(),"Anaheim.txt")}
930, 931, 934 | %{$CityHT.Add($_.ToString(),"SantaBarbara.txt")}
932, 933, 935 | %{$CityHT.Add($_.ToString(),"Bakersfield.txt")}
936, 937, 938 | %{$CityHT.Add($_.ToString(),"Fresno.txt")}
939, 950, 951 | %{$CityHT.Add($_.ToString(),"SanJose.txt")}
940, 941, 943, 944, 949, 954 | %{$CityHT.Add($_.ToString(),"SanFrancisco.txt")}
942, 952, 953, 956, 957,958,959 | %{$CityHT.Add($_.ToString(),"Sacramento.txt")}
945..948 | %{$CityHT.Add($_.ToString(),"Oakland.txt")}
955 | %{$CityHT.Add($_.ToString(),"Eureka.txt")}
960 | %{$CityHT.Add($_.ToString(),"Redding.txt")}

Это оставляет вам хеш-таблицу, которая будет соответствовать этим числам (в строковой форме) выходному файлу. Тогда вам просто нужно добавить все, что идет в Рено. Для этого вы можете использовать совпадения, автоматически сгенерированные Select-String.

#Get content and perform matching
$Content = Select-String -Path "*.txt" -Pattern ".{153}(\d{3})[0-9]{2,}"
#Add extra codes to Reno
$Content.Matches.Groups.Captures|?{$_.Name -eq '1' -and $_.Value -notin $CityHT.Keys}|Select -ExpandProperty Value -Unique|ForEach-Object{$CityHT.Add($_,"Reno.txt")}
#Add content to files by matches
$Content|ForEach{Add-Content -Value $_.Line -path $CityHT[$_.Matches.Groups[1].Value]}

Редактировать: Хорошо, я только что проверил это на нескольких файлах и сделал ревизию, чтобы она работала с несколькими файлами. Теперь, в соответствии с просьбой, давайте разберем второй кодовый блок. Первое, что мы делаем, это ищем подходящие шаблоны в ваших файлах. Командлет Select-String позволяет указать путь с допустимыми подстановочными знаками, по которому он будет пытаться выполнить сопоставление строк. Так что вместо того, чтобы читать файлы целиком, а затем подгонять это к Select-String, я просто делаю это за один шаг. Select-String выводит больше, чем просто совпадающие строки, он также выводит информацию о соответствии для каждой строки. Я слегка изменил ваш шаблон RegEx, добавив в него группу захвата, поэтому теперь он включает три цифры, которые нам нужны, как часть вывода. Если вы просто выводите его на экран, он показывает только исходный файл, номер строки и текст строки, но это еще не все. Давайте посмотрим на одну запись, переданную в Format-List:

IgnoreCase : True
LineNumber : 1
Line       : 123456          92345555                                                                2570 S Fake St    AVE                       280SNO                      CA  93725-1724
Filename   : datain.txt
Path       : C:\temp\datain.txt
Pattern    : .{153}(\d{3})[0-9]{2,}
Context    : 
Matches    : {0}

Теперь каждая строка, которая соответствует шаблону, имеет такую ​​запись. Из-за того, как обрабатываются совпадения, свойство Matches будет содержать свойство Groups, содержащее как минимум 1 запись и 1 дополнительную запись для каждой группы захвата, которая была у регулярного выражения (в нашем случае только 1 группа захвата). Поэтому, когда я ссылаюсь на .Matches.Groups[1].Value, я могу получить трехзначный код этой строки, который был в группе захвата.

Я использую это в следующей строке, где я перебираю все записи в $Content, проверяя, есть ли в этом 3-значном коде запись в хеш-таблице, которую мы создали ранее, и если она уже там, я отфильтровывайте его, пропуская только те коды, которые не учитываются по конвейеру с этим битом кода:

$Content.Matches.Groups.Captures|?{$_.Name -eq '1' -and $_.Value -notin $CityHT.Keys}

Это может передать много трехзначных кодов по конвейеру, многие из которых, я подозреваю, будут дубликатами, поэтому я передаю его |Select -Unique, чтобы получить только уникальные трехзначные коды. Те, которые я добавляю в хеш-таблицу и присваиваю Reno.txt, поэтому все, что не определено в первом разделе, автоматически отправляется в Reno.

Теперь, для последней строки ... Я передаю $Content в цикл и использую Add-Content, чтобы записать каждую строку в путь на основе захваченного значения. У нас есть хеш-таблица, которая преобразует трехзначный код в имя файла для связанного города, поэтому я просто ссылаюсь на него, чтобы определить, в какой файл записать каждую строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...