Maneira de listar e catar todos os arquivos que contenham string X no powershell

0

Atualmente, quando estou pesquisando um monte de arquivos para uma sequência no powershell, uso o seguinte:

PS: C:\> ls -r | Select-String "dummy" | ls -r

E isso lista todos os arquivos que têm essa string neles. Se eu fizer isso

PS: C:\> ls -r | Select-String "dummy" | ls -r | cat
PS: C:\> ls -r | Select-String "dummy" | cat

Ele pesquisará novamente e catará todos os arquivos que contiverem a string, mas tudo será exibido em um bloco como

file 1 line 1
file 1 line 2
file 2 line 1
file 3 line 1
file 4 line 1

Mas não há como saber qual linha está em qual arquivo. Existe uma maneira de listar algo como:

File 1.txt:
file1 line1
file2 line2

File 2.txt:
file2 line1

Um forro seria preferido, mas não necessário

    
por Mitch 23.09.2014 / 15:06

1 resposta

3

Alguém poderia argumentar que isso não é uma linha única, mas deve funcionar em qualquer caso ("deveria", significando que eu não testei, mas o script deveria estar certo):

Get-ChildItem -Recurse | Where-Object {(Select-String -InputObject $_ -Pattern 'dummy' -Quiet) -eq $true} | ForEach-Object {Write-Output $_; Get-Content $_}

Expandido, com comentários:

# Get a listing of all files within this folder and its subfolders.
Get-ChildItem -Recurse |

# Filter files according to a script.
Where-Object {
    # Pick only the files that contain the string 'dummy'.
    # Note: The -Quiet parameter tells Select-String to only return a Boolean. This is preferred if you just need to use Select-String as part of a filter, and don't need the output.
    (Select-String -InputObject $_ -Pattern 'dummy' -Quiet) -eq $true
} |

# Run commands against each object found.
ForEach-Object {
    # Output the file properties.
    Write-Output $_;

    # Output the file's contents.
    Get-Content $_
}

E aqui está uma versão "golfada", se você realmente quiser curta. Isso definitivamente se aproxima da qualificação como "one-liner".

ls -R|?{$_|Select-String 'dummy'}|%{$_;gc $_}

Além do uso óbvio de aliases, do recolhimento de espaços em branco e do truncamento de nomes de parâmetros, convém observar as seguintes diferenças significativas entre as versões "completa" e a versão "golfed":

  • Select-String foi trocado para usar entrada canalizada em vez de -InputObject .
  • O nome do parâmetro -Pattern foi omitido de Select-String , pois o uso do nome desse parâmetro é opcional.
  • A opção -Quiet foi eliminada de Select-String . O filtro ainda funcionará, mas levará mais tempo, pois Select-String processará cada arquivo completo em vez de parar após a primeira linha correspondente.
  • -eq $true foi omitido da regra de filtro. Quando um script de filtro já retorna um booleano, você não precisa adicionar um operador de comparação e um objeto se quiser que ele funcione quando o booleano for verdadeiro.
    • (Observe também que isso funcionará para alguns não-booleanos, como neste script. Aqui, uma correspondência resultará em um objeto de matriz preenchido, que é tratado como verdadeiro, enquanto que um não-correspondência retornará uma matriz vazia que é tratado como falso.)
  • Write-Output foi omitido. O PowerShell tentará fazer isso como uma ação padrão se um objeto for fornecido sem um comando.

Se você não precisa de todas as propriedades do arquivo, e quer apenas o caminho completo em uma linha antes do conteúdo do arquivo, você pode usar isto:

ls -R|?{$_|Select-String 'dummy'}|%{$_.FullName;gc $_}
    
por 23.09.2014 / 15:56

Tags