Powershell удалить пустые строки в файле
Я пытаюсь просто удалить первую строку около 5000 текстовых файлов перед их импортом.
Я все еще очень новичок в PowerShell, поэтому не уверен, что искать или как подойти к этому. Моя текущая концепция с использованием псевдо-кода:
однако я не могу понять, как сделать что-то вроде contains.
Это не самый эффективный в мире, но это должно работать:
в то время как я действительно восхищаюсь ответом от @hoge как для очень краткой техники, так и для функции обертки, чтобы обобщить ее, и я поощряю upvotes для нее, я вынужден комментировать два других ответа, которые используют временные файлы (он грызет меня, как ногти на доске!).
предполагая, что файл не огромен, вы можете заставить конвейер работать в дискретных секциях-тем самым устраняя необходимость в временном файле-с разумным использованием скобки:
. или в краткой форме:
используя переменную нотацию, вы можете сделать это без временного файла:
мне просто нужно было выполнить ту же задачу, и gc | select . | sc взял на себя 4 ГБ ОЗУ на моей машине при чтении файла 1.6 GB. Он не заканчивался по крайней мере в течение 20 минут после чтения всего файла (как сообщает Read Bytes in Процесс Explorer), и в этот момент мне пришлось убить его.
ниже мое решение. Да, он использует временный файл, но в моем случае это не имело значения (это было чертовски огромное создание таблицы SQL и файл инструкций insert):
вдохновленный ответ AASoft, Я вышел, чтобы улучшить его немного подробнее:
- избежать переменная цикла $i и сравнение С 0 в каждом цикле
- оберните исполнение в try..finally блок, чтобы всегда закрывать файлы в использовании
- сделать решение работать для произвольное количество строк удалить С начала файла
- использовать переменную $p для ссылки на текущий каталог
эти изменения приводят к следующим кодом:
первое изменение принесло время обработки для моего файла 60 MB вниз от 5.3s to 4s . Остальные изменения носят более косметический характер.
Я только что узнал из сайта:
или вы можете использовать псевдонимы, чтобы сделать это коротко, как:
skip` не работает, поэтому мой обходной путь
именно столько. Далее следует длинное скучное объяснение. Get-content возвращает массив. Мы можем "индексировать" переменные массива, как показано в этой и другое сценаристы посты.
например, если мы определяем переменную массива, как это,
Итак, $ array возвращает
тогда мы можем "индексировать" этот массив, чтобы получить только его 1-й элемент
или только его 2-й
или ряд значений индекса от 2-го до последнего.
для небольших файлов вы можете использовать это:
& C:\windows\system32\more +1 oldfile.csv > новый файл.CSV-файл | выход-нуль
. но это не очень эффективно при обработке моего примера файла 16MB. Кажется, он не завершает и не освобождает блокировку newfile.csv.
to remove empty lines. But How I can remove them with '-replace' ?
My answer removes empty lines with the -replace comparison operator. Get-Content doesn't have a replace parameter, so I'm assuming you're looking for a way to do it with the operator.
13 Answers 13
See the original for some notes about the code. Nice :)
I think on balance I prefer (gc file.txt) | ? < -not $_.IsNullOrWhiteSpace() >| set-content file.txt because it expresses the intent more clearly, but it amounts to the same thing.
On brief glance, I do not seem to have the "IsNullOrWhiteSpace()" method on my strings. and. how could an instance method check for null? The posted answer works great though!
The IsNullOrWhiteSpace is a static method from System.String object the proper way to call it in PowerShell is as follow : [String]::IsNullOrWhiteSpace(
This piece of code from Randy Skretka is working fine for me, but I had the problem, that I still had a newline at the end of the file.
So I added finally this:
You can use -match instead -eq if you also want to exclude files that only contain whitespace characters:
Not specifically using -replace , but you get the same effect parsing the content using -notmatch and regex.
This worked like charm. I was attempting to remove VB6 comments from a file and this was the final command I used - (Get-Content -Path ".\vbXML.cls") -replace "\'.*$", "" -notmatch "^\s*$" | Out-File ".\vbXML.uncommented.cls" -Append
To resolve this with RegEx, you need to use the multiline flag (?m):
If you actually want to filter blank lines from a file then you may try this:
You can't do replacing, you have to replace SOMETHING with SOMETHING, and you neither have both.
You're talking apples and oranges. Remove and Replace are clearly different. What you have will basically work, but perhaps you are trying to rebuild the existing file but without the blanks. PS C:\> $text=get-content a.txt PS C:\> $text | where | out-file a.txt$_>
This will remove empty lines or lines with only whitespace characters (tabs/spaces).
file
PS /home/edward/Desktop> Get-Content ./copy.txt
[Desktop Entry]
Name=calibre Exec=~/Apps/calibre/calibre
Icon=~/Apps/calibre/resources/content-server/calibre.jpg
Type=Application*
Start by get the content from file and trim the white spaces if any found in each line of the text document. That becomes the object passed to the where-object to go through the array looking at each member of the array with string length greater then 0. That object is passed to replace the content of the file you started with. It would probably be better to make a new file. Last thing to do is reads back the newly made file's content and see your awesomeness.
(Get-Content ./copy.txt).Trim() | Where-Object | Set-Content ./copy.txt
Get-Content ./copy.txt
Для удаления пустых строк. Но как я могу удалить их с помощью «-replace»?
Мой ответ удаляет пустые строки с помощью оператора сравнения -replace . Get-Content не имеет параметра замены, поэтому я предполагаю, что вы ищете способ сделать это с помощью оператора.
См. оригинал для некоторых примечаний о коде. Хороший :)
Я думаю, что в целом я предпочитаю (gc file.txt) | ? < -not $_.IsNullOrWhiteSpace() >| set-content file.txt , потому что это более четко выражает намерение, но это то же самое.
На первый взгляд, у меня нет метода "IsNullOrWhiteSpace()" в моих строках. и. как метод экземпляра может проверить значение null? Опубликованный ответ отлично работает!
IsNullOrWhiteSpace — это статический метод из объекта System.String. Правильный способ вызова его в PowerShell выглядит следующим образом: [String]::IsNullOrWhiteSpace(
Этот фрагмент кода от Рэнди Скретки у меня работает нормально, но у меня была проблема, что у меня все еще была новая строка в конце файла.
Итак, я добавил, наконец, это:
Вы можете использовать -match вместо -eq, если вы также хотите исключить файлы, которые содержат только символы пробела:
Специально не используя -replace , но вы получаете тот же эффект при анализе содержимого с помощью -notmatch и регулярного выражения.
Это сработало как шарм. Я пытался удалить комментарии VB6 из файла, и это была последняя команда, которую я использовал — (Get-Content -Path ".\vbXML.cls") -replace "\'.*$", "" -notmatch "^\s*$" | Out-File ".\vbXML.uncommented.cls" -Append
Чтобы решить эту проблему с помощью RegEx, вам нужно использовать многострочный флаг (?m):
Если вы действительно хотите отфильтровать пустые строки из файла, вы можете попробовать следующее:
Это удалит пустые строки или строки, содержащие только пробельные символы (табуляции/пробелы).
Начните с получения содержимого из файла и обрежьте пробелы, если они есть в каждой строке текстового документа. Это становится объектом, переданным объекту where, чтобы пройти через массив, просматривая каждый элемент массива с длиной строки больше 0. Этот объект передается для замены содержимого файла, с которого вы начали. Вероятно, было бы лучше создать новый файл. Последнее, что нужно сделать, это прочитать содержимое только что созданного файла и увидеть, насколько он великолепен.
(Get-Content ./copy.txt).Trim() | Where-Object | Set-Content ./copy.txt
Get-Content ./copy.txt
Это удаляет завершающие пробелы и пустые строки из файла.txt.
Вы не можете заменить, вы должны заменить ЧТО-ТО на ЧТО-ТО, и у вас нет ни того, ни другого.
чтобы удалить пустые строки, которые SSRS помещает в конец моих CSV.
Однако последняя строка, в которой есть данные, заканчивается CRLF (как показано в Notepad++) — и это не удаляется, поэтому технически в нижней части файла по-прежнему остается пустая строка.
Есть ли способ удалить этот CRLF из последней строки (и, конечно, сохранить данные нетронутыми)?
задан 25 июля '12, 06:07
Это не "технически". Если файл не заканчивается на CR LF CR LF, в конце нет пустой строки. Технически. - Ignacio Vazquez-Abrams
Игнасио, это зависит от того, понимаешь ли ты это как строку разделитель или линия терминатор ;) - Joey
5 ответы
Если вы уже знаете, что самая последняя вещь в файле — это CRLF, от которого вы хотите избавиться (и вы также знаете кодировку), вы можете пойти быстрым путем:
Это усечение файла на месте. Работает без считывания всего файла в память (очень приятно, если у вас есть очень большой файл). Он работает для ASCII, Latin-* и UTF-8. Это не будет работать для UTF-16 (в этом случае вам придется удалить четыре байта с конца).
Вы можете включить дополнительную проверку того, что последние два байта на самом деле что вы хотите удалить:
Опять же, адаптируйтесь, если вы используете другую кодировку, например, для UTF-16 вам нужно сравнить либо 0,10,0,13 or 10,0,13,0 .
Согласитесь, это не очень PowerShell-ey, но с тех пор, как мне пришлось обрабатывать дамп базы данных размером 700 МБ, я опасаюсь полностью считывать потенциально большие файлы в память;)
Создан 25 июля '12, 08:07
Это выглядит как хорошее решение, но я получаю эту ошибку: Исключение, вызывающее «SetLength» с аргументом (ами) «1»: «Требуется неотрицательное число. Имя параметра: значение» В строке: 2 char: 18 + $stream. SetLength
Что ж, похоже, вы делаете это с пустым файлом (которого в первом примере может не быть ранее). - Джо
Не могу воспроизвести это здесь. Код сработал у меня и правильно удалил последние два байта, в последнем примере, только если они действительно были CRLF. - Джо
Я заработал. имя файла в первой строке ДОЛЖНО было быть полным ("C:\File.txt"). Спасибо! - Stuartdotnet
В моем случае это всего лишь удаление нескольких символов, а не удаление всей последней строки. - Дэвид Гарсия
Когда вы читаете файл с помощью Get-Content он передает каждую строку по каналу в виде строки. Когда Out-File (по сути что > является псевдонимом для) получает эти строки, он всегда добавляет последовательность конца строки. Попробуйте следующее, если файлы не слишком большие:
удалить пустые строки. Но как я могу удалить их с помощью -replace?
задан 10 фев '12, 02:02
Почему вы хотите заменить? И работайте над своей приемкой - manojlds
Мой ответ удаляет пустые строки с -replace оператор сравнения. Get-Content не имеет параметра замены, поэтому я предполагаю, что вы ищете способ сделать это с помощью оператора. - Andy Arismendi
11 ответы
Некоторые примечания к коду см. В оригинале. Хороший :)
Я думаю, что в целом я предпочитаю (gc file.txt) | ? < -not $_.IsNullOrWhiteSpace() >| set-content file.txt потому что он более четко выражает намерение, но сводится к тому же самому. - Нил Барнуэлл
На первый взгляд кажется, что у меня нет метода "IsNullOrWhiteSpace ()" в моих строках . и . как метод экземпляра может проверить значение null? Опубликованный ответ отлично работает! - xdhmoore
IsNullOrWhiteSpace - это статический метод из объекта System.String, правильный способ вызвать его в PowerShell выглядит следующим образом: [String]::IsNullOrWhiteSpace() . Правильная основа командной строки на комментарии Нила Барнуэлла выглядит следующим образом: (gc file.txt) | ? < -not [String]::IsNullOrWhiteSpace($_) >| set-content file.txt - LMA1980
Этот фрагмент кода от Рэнди Скретки у меня работает нормально, но у меня была проблема, что у меня все еще была новая строка в конце файла.
Итак, я наконец добавил это:
ответ дан 08 мар '16, в 16:03
Вы можете использовать -match вместо -eq, если вы также хотите исключить файлы, содержащие только символы пробела:
Специально не используя -replace , но вы получите тот же эффект, если проанализируете контент с помощью -notmatch и регулярное выражение.
ответ дан 13 авг.
Это сработало как шарм. Я пытался удалить комментарии VB6 из файла, и это была последняя команда, которую я использовал - (Get-Content -Path ".\vbXML.cls") -replace "\'.*$", "" -notmatch "^\s*$" | Out-File ".\vbXML.uncommented.cls" -Append - Шива Сентил
Чтобы решить эту проблему с помощью RegEx, вам необходимо использовать многострочный флаг (? M):
Если вы действительно хотите отфильтровать пустые строки из файла, вы можете попробовать следующее:
(gc $ source_file) .Trim () | ?
ответ дан 08 мар '18, в 13:03
Вы не можете выполнить замену, вы должны заменить ЧТО-ТО на ЧТО-ТО, и у вас ни того, ни другого нет и того, и другого.
поддержка Poowershell -remove "" для удаления пустых строк? - Сулиман
Нет, похоже, что у него нет поддержки «-remove». - Сулиман
Вы говорите о яблоках и апельсинах. Удалить и заменить явно разные. То, что у вас есть, в основном будет работать, но, возможно, вы пытаетесь восстановить существующий файл, но без пробелов. PS C: \> $ text = get-content a.txt PS C: \> $ text | где | Out-файл a.txt - Джеффри Хикс
Это удалит пустые строки или строки, содержащие только символы пробела (табуляции / пробелы).
ответ дан 19 дек '14, 17:12
Начните с получения содержимого из файла и обрежьте пробелы, если они есть в каждой строке текстового документа. Это становится объектом, переданным объекту where, чтобы пройти через массив, глядя на каждый член массива с длиной строки больше 0. Этот объект передается для замены содержимого файла, с которого вы начали. Возможно, лучше было бы создать новый файл . Последнее, что нужно сделать, это прочитать содержимое только что созданного файла и посмотреть, насколько вы хороши.
(Get-Content ./copy.txt).Trim() | Where-Object | Set-Content ./copy.txt
Get-Content ./copy.txt
Читайте также: